Javascript의 객체에서 빈 속성 제거


265

undefined또는 모든 속성을 제거하려면 어떻게합니까nullJavaScript 객체에 JavaScript 객체에있는 합니까?

(질문과 유사한 이 하나의 배열에 대한)


19
사람들이 최고 순위를 무시하고 ES6 / ES7 버전으로 이동하라고 제안하십시오. stackoverflow.com/a/38340730/124486
Evan Carroll

2
또한 객체를 변경하지 않고 ES6 하나의 라이너가 있습니다 : stackoverflow.com/a/57625661/1602301
Chickens

답변:


184

객체를 반복 할 수 있습니다.

var test = {
    test1 : null,
    test2 : 'somestring',
    test3 : 3,
}

function clean(obj) {
  for (var propName in obj) { 
    if (obj[propName] === null || obj[propName] === undefined) {
      delete obj[propName];
    }
  }
}

clean(test);

이 속성 제거가 객체의 proptype chain을 실행하지 않는 것에 대해 우려되는 경우 다음을 수행 할 수도 있습니다.

function clean(obj) {
  var propNames = Object.getOwnPropertyNames(obj);
  for (var i = 0; i < propNames.length; i++) {
    var propName = propNames[i];
    if (obj[propName] === null || obj[propName] === undefined) {
      delete obj[propName];
    }
  }
}

null 대 undefined에 대한 몇 가지 참고 사항 :

test.test1 === null; // true
test.test1 == null; // true

test.notaprop === null; // false
test.notaprop == null; // true

test.notaprop === undefined; // true
test.notaprop == undefined; // true

2
빠른 수정이 추가되었습니다. 이 스 니펫이 함수에서 사용 된 경우 선언되지 않은 "i"변수는 외부 범위로 누출됩니다.
Eric Nguyen

4
(test [i] == null || test [i] === undefined)를 (test [i] == null)로 단순화 할 수 있습니다.
jaf0

안녕하세요, @EricNguyen은 C 및 기타 여러 언어와 달리 javascript에는 변수에 대한 블록 범위 가 없으며 (함수 범위에만 해당) 변수 i 는 항상 for 블록 다음에 범위로 누출됩니다 .
제라르도 리마

1
@GerardoLima, 그렇습니다. 나는 이것이 모두 함수에 싸여 있다고 가정했다. 내가 (이 모든 기능과 함께 포장입니다 가정)을 의미하는 것은 당신이 VAR 선언이 필요하거나 것입니다 내가 심지어 외부 함수 범위의 누출됩니다.
Eric Nguyen

이것은 또한 기본 객체의 프로토 타입을 반복하며 대부분의 경우 바람직하지 않습니다. stackoverflow.com/a/2869372/1612318
Rotareti

427

일부 ES6 / ES2015 사용 :

1) 간단한 원 라이너로 할당없이 항목을 인라인 으로 제거합니다 .

Object.keys(myObj).forEach((key) => (myObj[key] == null) && delete myObj[key]);

jsbin

2) 이 예는 제거되었습니다 ...

3) 함수로 작성된 첫 번째 예 :

const removeEmpty = obj => {
  Object.keys(obj).forEach(key => obj[key] == null && delete obj[key]);
};

jsbin

4)이 함수는 재귀 를 사용 하여 중첩 된 객체에서 항목을 삭제합니다.

const removeEmpty = obj => {
  Object.keys(obj).forEach(key => {
    if (obj[key] && typeof obj[key] === "object") removeEmpty(obj[key]); // recurse
    else if (obj[key] == null) delete obj[key]; // delete
  });
};

jsbin

4b) 이것은 4)와 비슷하지만 소스 객체를 직접 변경하는 대신 새 객체를 반환합니다.

const removeEmpty = obj => {
  const newObj = {};

  Object.keys(obj).forEach(key => {
    if (obj[key] && typeof obj[key] === "object") {
      newObj[key] = removeEmpty(obj[key]); // recurse
    } else if (obj[key] != null) {
      newObj[key] = obj[key]; // copy value
    }
  });

  return newObj;
};

5) 기능 을 기반 4B에 접근) MichaelJ.Zoidl의 대답은 @ 사용 filter()하고 reduce(). 이것도 새로운 객체를 반환합니다 :

const removeEmpty = obj =>
  Object.keys(obj)
    .filter(k => obj[k] != null) // Remove undef. and null.
    .reduce(
      (newObj, k) =>
        typeof obj[k] === "object"
          ? { ...newObj, [k]: removeEmpty(obj[k]) } // Recurse.
          : { ...newObj, [k]: obj[k] }, // Copy value.
      {}
    );

jsbin

6) 4)와 동일하지만 ES7 / 2016 과 동일 Object.entries()합니다.

const removeEmpty = (obj) => 
  Object.entries(obj).forEach(([key, val]) => {
    if (val && typeof val === 'object') removeEmpty(val)
    else if (val == null) delete obj[key]
})

5b) 재귀를 사용하고 ES2019 로 새 객체를 반환하는 다른 기능 버전 : Object.fromEntries()

const removeEmpty = obj =>
  Object.fromEntries(
    Object.entries(obj)
      .filter(([k, v]) => v != null)
      .map(([k, v]) => (typeof v === "object" ? [k, removeEmpty(v)] : [k, v]))
  );

7) 4)와 동일하지만 일반 ES5 :

function removeEmpty(obj) {
  Object.keys(obj).forEach(function(key) {
    if (obj[key] && typeof obj[key] === 'object') removeEmpty(obj[key])
    else if (obj[key] == null) delete obj[key]
  });
};

jsbin


3
@AugustinRiedinger 줄 바꿈과 약어를 결정해야 할 때 약어가 덜 악하다고 생각하면 약어를 사용하는 경우가 있습니다. 5의 코드는)에 대한 이유를 어렵지 않습니다 그것은 빈 제거하는 기능입니다 keys에서 object, 그렇게 o하고 k명백하다. 그러나 나는 그것이 맛의 문제라고 생각합니다.
Rotareti

3
ES5 맛을 가진 첫 번째 버전 :Object.keys(myObj).forEach(function (key) {(myObj[key] == null) && delete myObj[key]});
신경 전달 물질

1
기능없이 한 줄 :Object.entries(myObj).reduce((acc, [key, val]) => { if (val) acc[key] = val; return acc; }, {})
Paul Slm

7
철저하게 노력하고 있으므로 불변의 해결책을 보는 것이 좋습니다. 소스 오브젝트를 변경하고 있으며 오브젝트가 변경 되었기 때문에 실제로 불필요한 오브젝트를 기만적으로 리턴합니다. 초보자는 반환 된 객체 값을 캡처하고 소스 객체도 수정 된 이유를 궁금해합니다.
Mike McLin

2
5) 배열과 작동하지 않습니다 (Object.keys는 배열 위치 번호를 요소의 키로 반환합니다). 아마도 다른 사람들이 문제를 가지고 있지만, 5. 테스트 할 때 나는이 발견
Eelco

95

lodash 또는 underscore.js를 사용하는 경우 간단한 해결책은 다음과 같습니다.

var obj = {name: 'John', age: null};

var compacted = _.pickBy(obj);

이것은 lodash 4, pre lodash 4 또는 underscore.js에서만 작동합니다 _.pick(obj, _.identity).


1
훌륭한! 감사합니다! 참고로, 나에게 분명하지 않은 것은 다음과 같이 사용할 수 있다는 것입니다. foo (). then (_. pickBy); // 빈 결과를 필터링
마치에이 Gurban

29
개체에 0 또는 빈 문자열과 같은 잘못된 값이 포함되어 있으면 원하는 결과를 얻지 못합니다. 그렇다면 _.omit(obj, _.isUndefined)더 좋습니다.
JHH

5
@JHH은 _.isUndefined생략 널은, 사용하지 않는 _.omitBy(obj, _.isNil)모두를 생략 undefined하고null
루카스 Wiktor

@LukaszWiktor 맞습니다. 질문은 정의되지 않았거나 null을 요구했습니다.
JHH

85

ES6 + 용 최단 라이너

모든 falsy 값을 필터 ( "", 0, false, null, undefined)

Object.entries(obj).reduce((a,[k,v]) => (v ? (a[k]=v, a) : a), {})

필터 nullundefined값 :

Object.entries(obj).reduce((a,[k,v]) => (v == null ? a : (a[k]=v, a)), {})

필터 만 null

Object.entries(obj).reduce((a,[k,v]) => (v === null ? a : (a[k]=v, a)), {})

필터 만 undefined

Object.entries(obj).reduce((a,[k,v]) => (v === undefined ? a : (a[k]=v, a)), {})

재귀 솔루션 : 필터nullundefined

객체의 경우 :

const cleanEmpty = obj => Object.entries(obj)
        .map(([k,v])=>[k,v && typeof v === "object" ? cleanEmpty(v) : v])
        .reduce((a,[k,v]) => (v == null ? a : (a[k]=v, a)), {});

객체와 배열의 경우 :

const cleanEmpty = obj => {
  if (Array.isArray(obj)) { 
    return obj
        .map(v => (v && typeof v === 'object') ? cleanEmpty(v) : v)
        .filter(v => !(v == null)); 
  } else { 
    return Object.entries(obj)
        .map(([k, v]) => [k, v && typeof v === 'object' ? cleanEmpty(v) : v])
        .reduce((a, [k, v]) => (v == null ? a : (a[k]=v, a)), {});
  } 
}

10
이것이 유일한 대답이어야합니다! 이러한 각 스 니펫은 이전 오브젝트가 변경되지 않는 새 오브젝트를 생성합니다. 이것은 바람직하다! 약간의 메모가 당신이 사용하는 단지 경우에 v == null당신이에 대해 확인합니다 undefinednull.
Megajin

cleanEmptyrecursve 솔루션은 빈 개체를 반환 {}날짜 개체에 대한
엠마뉴엘 NK

하나의 라이너에 조금 더 가독성이 좋을 것입니다!
zardilior

39

누군가 Owen과 Eric의 재귀 버전이 필요한 경우 다음과 같습니다.

/**
 * Delete all null (or undefined) properties from an object.
 * Set 'recurse' to true if you also want to delete properties in nested objects.
 */
function delete_null_properties(test, recurse) {
    for (var i in test) {
        if (test[i] === null) {
            delete test[i];
        } else if (recurse && typeof test[i] === 'object') {
            delete_null_properties(test[i], recurse);
        }
    }
}

for 루프가 시작된 후 다음을 hasOwnProperty사용 하여 객체 를 확인해야합니다.if(test.hasOwnProperty(i)) { ... }
Augie Gardner

@AugieGardner 왜 이것을 확인하고 싶은지 궁금합니다. 원한다면 설명해주세요. (상속 된 속성의 확인을 막을 수 없습니까?)
Wumms

24

JSON.stringify는 정의되지 않은 키를 제거합니다.

removeUndefined = function(json){
  return JSON.parse(JSON.stringify(json))
}

이것은 깊은 물체에 대해서는 효과가 없었지만 위의 Wumm의 대답 은 그랬습니다.
Suman

1
교체 기능 nullundefined사용하는 것으로 취급 되어야 하는 경우 자세한 내용은 다음 답변을 참조하십시오. stackoverflow.com/questions/286141/…
Hooman Askari

이것이 null값을 제거하지는 않습니다 . let a = { b: 1, c: 0, d: false, e: null, f: undefined, g: [], h: {} }다음을 시도하십시오 console.log(removeUndefined(a)). 질문 undefinednull가치 에 관한 것이 었습니다 .
mayid

13

당신은 아마 delete키워드를 찾고 있습니다.

var obj = { };
obj.theProperty = 1;
delete obj.theProperty;

4
이것은 그가 위에서하고있는 일이며, 여전히 객체에서 정의되지 않은 채로 둡니다.
Josh Bedo

10

nullundefined값이 필터링 된 객체를 반환하는 가장 간단한 Lodash 솔루션 입니다.

_.omitBy(obj, _.isNil)


이것은 지금까지 가장 깨끗한 솔루션입니다!
Jee Mok

9

JSON.stringifyreplacer 매개 변수 의 조합을 사용하여 JSON.parse다시 객체로 전환 할 수 있습니다. 또한이 방법을 사용하면 중첩 된 개체 내의 모든 중첩 키가 교체됩니다.

예제 객체

var exampleObject = {
  string: 'value',
  emptyString: '',
  integer: 0,
  nullValue: null,
  array: [1, 2, 3],
  object: {
    string: 'value',
    emptyString: '',
    integer: 0,
    nullValue: null,
    array: [1, 2, 3]
  },
  arrayOfObjects: [
    {
      string: 'value',
      emptyString: '',
      integer: 0,
      nullValue: null,
      array: [1, 2, 3]
    },
    {
      string: 'value',
      emptyString: '',
      integer: 0,
      nullValue: null,
      array: [1, 2, 3]
    }
  ]
};

대체 기능

function replaceUndefinedOrNull(key, value) {
  if (value === null || value === undefined) {
    return undefined;
  }

  return value;
}

물체 청소

exampleObject = JSON.stringify(exampleObject, replaceUndefinedOrNull);
exampleObject = JSON.parse(exampleObject);

CodePen 예


6

사용 ramda 번호 pickBy 모든 제거 null, undefinedfalse값 :

const obj = {a:1, b: undefined, c: null, d: 1}
R.pickBy(R.identity, obj)

@manroe가 지적했듯이 false값 을 유지 하려면 isNil()다음을 사용하십시오 .

const obj = {a:1, b: undefined, c: null, d: 1, e: false}
R.pickBy(v => !R.isNil(v), obj)

1
(v) => !R.isNil(v)false또는 다른 잘못된 값들에 의해 거부 될 것이라는 점을 감안할 때 OP의 질문에 더 나은 선택 일 것입니다R.identity
manroe

6

.filter필요한 것보다 많은 객체를 생성하거나 포함하지 않고 기능적이고 불변의 접근 방식

Object.keys(obj).reduce((acc, key) => (obj[key] === undefined ? acc : {...acc, [key]: obj[key]}), {})

매우 간결한 답변. 또한 널 체크 그냥 교체 추가 obj[key] === undefinedobj[key] === undefined || obj[key] === null
user3658510

위의 접근 방식의 약간의 변형 : 당신은 또한 조건부처럼 obj 속성에 조건부로 퍼질 수 있습니다const omitFalsy = obj => Object.keys(obj).reduce((acc, key) => ({ ...acc, ...(obj[key] && { [key]: obj[key] }) }), {});
Kevin K.

5

당신은 !조건으로 더 짧은 할 수 있습니다

var r = {a: null, b: undefined, c:1};
for(var k in r)
   if(!r[k]) delete r[k];

사용법에서 기억 : @semicolor가 주석에서 알 수 있듯이 : 값이 빈 문자열, false 또는 0 인 경우 속성도 삭제됩니다.


11
값이 빈 문자열, false 또는 0 인 경우 속성도 삭제됩니다.
세미콜론

3
이것은 정확히 JSON 요청에서 원하지 않는 필드를 제거하기 위해 찾고 있던 것입니다. 감사!
Phrozen

[null, undefined].includes(r[k])대신에 사용하십시오 !r[k].
selmansamet

5

더 짧은 ES6 순수 솔루션은 배열로 변환하고 필터 기능을 사용하여 다시 객체로 변환합니다. 기능을 쉽게 만들 수 있습니다 ...

Btw. 이것을 사용 .length > 0하여 빈 문자열 / 배열이 있는지 확인하므로 빈 키를 제거합니다.

const MY_OBJECT = { f: 'te', a: [] }

Object.keys(MY_OBJECT)
 .filter(f => !!MY_OBJECT[f] && MY_OBJECT[f].length > 0)
 .reduce((r, i) => { r[i] = MY_OBJECT[i]; return r; }, {});

JS BIN https://jsbin.com/kugoyinora/edit?js,console


1
좋은 기능성 솔루션
puiu

나는 이것을 좋아한다! 하지만 모두 제거 생각 null하고 undefined그냥 사용에 간단 할 것입니다 MY_OBJECT[f] != null. 현재 솔루션은 비어 있지 않은 문자열 / 목록을 제외한 모든 것을 제거하고 값이 다음과 같은 경우 오류를 발생 null
시킵니다.

맞다, 당신은 또한 여러 개의 / 체인을 사용할 수 filter있고 더 읽기 쉽습니다.
Michael J. Zoidl

이것을 약간 일반화하면 loadash의 기능에 가까워 진다고 생각 omit하기 전에 obj가 존재하는지 확인해야합니다 Object.keys.const omit = (obj, filter) => obj && Object.keys(obj).filter(key => !filter(obj[key])).reduce((acc,key) => {acc[key] = obj[key]; return acc}, {});
icc97

멋지지만이 접근법으로 모든 정수 값이 제거됩니다.
Ghis

5

json.stringify의 replacer 인수를 사용하여 한 줄로 재귀 제거를 수행 할 수 있습니다

const removeNullValues = obj => (
  JSON.parse(JSON.stringify(obj, (k,v) => v ?? undefined))
)

용법:

removeNullValues({a:{x:1,y:null,z:undefined}}) // Returns {a:{x:1}}

Emmanuel의 의견에서 언급 했듯이이 기술은 데이터 구조에 JSON 형식 (문자열, 숫자, 목록 등)으로 넣을 수있는 데이터 유형 만 포함하는 경우에만 작동했습니다.

(이 답변은 새로운 Nullish Coalescing 연산자 를 사용하도록 업데이트되었습니다 . 브라우저 지원 요구에 따라이 기능을 대신 사용할 수 있습니다. (k,v) => v!=null ? v : undefined)


1
그러면 Date 객체가 문자열로 변환 NaN되고 null제거되지 않은 것으로 변환 됩니다.
Emmanuel NK

4

순수한 ES7 솔루션의 4 줄을 원한다면 :

const clean = e => e instanceof Object ? Object.entries(e).reduce((o, [k, v]) => {
  if (typeof v === 'boolean' || v) o[k] = clean(v);
  return o;
}, e instanceof Array ? [] : {}) : e;

또는 더 읽기 쉬운 버전을 선호하는 경우 :

function filterEmpty(obj, [key, val]) {
  if (typeof val === 'boolean' || val) {
    obj[key] = clean(val)
  };

  return obj;
}

function clean(entry) {
  if (entry instanceof Object) {
    const type = entry instanceof Array ? [] : {};
    const entries = Object.entries(entry);

    return entries.reduce(filterEmpty, type);
  }

  return entry;
}

부울 값을 유지하고 배열도 정리합니다. 또한 정리 된 복사본을 반환하여 원본 개체를 유지합니다.


4

내 프로젝트에서 동일한 시나리오가 있으며 다음 방법을 사용하여 달성했습니다.

모든 데이터 유형에서 작동하지만 위에서 언급 한 것은 날짜 및 빈 배열에서는 작동하지 않습니다.

removeEmptyKeysFromObject.js

removeEmptyKeysFromObject(obj) {
   Object.keys(obj).forEach(key => {
  if (Object.prototype.toString.call(obj[key]) === '[object Date]' && (obj[key].toString().length === 0 || obj[key].toString() === 'Invalid Date')) {
    delete obj[key];
  } else if (obj[key] && typeof obj[key] === 'object') {
    this.removeEmptyKeysFromObject(obj[key]);
  } else if (obj[key] == null || obj[key] === '') {
    delete obj[key];
  }

  if (obj[key]
    && typeof obj[key] === 'object'
    && Object.keys(obj[key]).length === 0
    && Object.prototype.toString.call(obj[key]) !== '[object Date]') {
    delete obj[key];
  }
});
  return obj;
}

이 함수에 객체를 전달하십시오 removeEmptyKeysFromObject ()


4

심층 검색을 위해 다음 코드를 사용 했는데이 질문을 보는 모든 사람에게 유용 할 것입니다 (순환 종속성에는 사용할 수 없습니다).

function removeEmptyValues(obj) {
        for (var propName in obj) {
            if (!obj[propName] || obj[propName].length === 0) {
                delete obj[propName];
            } else if (typeof obj[propName] === 'object') {
                removeEmptyValues(obj[propName]);
            }
        }
        return obj;
    }

3

제자리에서 변경하지 않고 null / undefined가 제거 된 클론을 반환하는 경우 ES6 reduce 기능을 사용할 수 있습니다.

// Helper to remove undefined or null properties from an object
function removeEmpty(obj) {
  // Protect against null/undefined object passed in
  return Object.keys(obj || {}).reduce((x, k) => {
    // Check for null or undefined
    if (obj[k] != null) {
      x[k] = obj[k];
    }
    return x;
  }, {});
}

3

속성을 삭제하는 대신 null이 아닌 키를 사용하여 새 객체를 만들 수도 있습니다.

const removeEmpty = (obj) => {
  return Object.keys(obj).filter(key => obj[key]).reduce(
    (newObj, key) => {
      newObj[key] = obj[key]
      return newObj
    }, {}
  )
}

3

에 piggypack에 벤의 대답 lodash의를 사용하여이 문제를 해결하는 방법 _.pickBy: 당신은 또한 자매 라이브러리에서이 문제를 해결할 수 Underscore.js '들 _.pick.

var obj = {name: 'John', age: null};

var compacted = _.pick(obj, function(value) {
  return value !== null && value !== undefined;
});

JSFiddle 예제를 참조하십시오.


1
이것은 빈 배열을 반환합니다. 또한 obj의 이름을 object로 변경했습니다.
Stephen DuMont

스티븐 감사합니다! 지금은 어때? JSFiddle 링크를 포함하도록 답변을 업데이트했습니다.
Alex Johnson

_.omit (obj, _.isEmpty); 이것은 개념적으로 더 순수하며 빈 문자열을 포함합니다.
Stephen DuMont

3

감소 도우미가 유형 검사없이 트릭을 수행 할 수 있습니다.

const cleanObj = Object.entries(objToClean).reduce((acc, [key, value]) => {
      if (value) {
        acc[key] = value;
      }
      return acc;
    }, {});

2

누군가가 undefined심층 검색을 사용하여 객체에서 값 을 제거 해야하는 경우 lodash여기에 내가 사용하는 코드가 있습니다. 모든 빈 값 ( null/ undefined) 을 제거하도록 수정하는 것은 매우 간단합니다 .

function omitUndefinedDeep(obj) {
  return _.reduce(obj, function(result, value, key) {
    if (_.isObject(value)) {
      result[key] = omitUndefinedDeep(value);
    }
    else if (!_.isUndefined(value)) {
      result[key] = value;
    }
    return result;
  }, {});
}


1

eslint를 사용하고 매개 변수 없음 재 지정 규칙이 트립되지 않도록하려면 Object.assign을 .reduce 및 계산 된 속성 이름과 함께 사용하여 매우 우아한 ES6 솔루션을 사용할 수 있습니다.

const queryParams = { a: 'a', b: 'b', c: 'c', d: undefined, e: null, f: '', g: 0 };
const cleanParams = Object.keys(queryParams) 
  .filter(key => queryParams[key] != null)
  .reduce((acc, key) => Object.assign(acc, { [key]: queryParams[key] }), {});
// { a: 'a', b: 'b', c: 'c', f: '', g: 0 }

1

다음을 nulls사용하여 객체를 변경하지 않고 ES6을 사용하여 객체에서 제거하는 기능적인 방법은 다음과 같습니다 reduce.

const stripNulls = (obj) => {
  return Object.keys(obj).reduce((acc, current) => {
    if (obj[current] !== null) {
      return { ...acc, [current]: obj[current] }
    }
    return acc
  }, {})
}

트롤 코멘트이 기능적인 패턴에 관한 두 가지 : stripNulls함수 내 에서 누산기 함수의 범위 밖에서 참조를 사용합니다. 또한 누산기 기능 내에서 필터링하여 문제를 혼합합니다. 😝 (예 Object.entries(o).filter(([k,v]) => v !== null).reduce((o, [k, v]) => {o[k] = v; return o;}, {});) 예, 그것은 필터링 항목을 통해 루프를 두 번하지만 무시할가 손실를 규칙적 실현됩니다.
Jason Cust

1

다음과 같이 ...스프레드 구문을 사용할 수도 있습니다 forEach.

let obj = { a: 1, b: "b", c: undefined, d: null };
let cleanObj = {};

Object.keys(obj).forEach(val => {
  const newVal = obj[val];
  cleanObj = newVal ? { ...cleanObj, [val]: newVal } : cleanObj;
});

console.info(cleanObj);

1

깨끗한 물체

// General cleanObj function
const cleanObj = (valsToRemoveArr, obj) => {
   Object.keys(obj).forEach( (key) =>
      if (valsToRemoveArr.includes(obj[key])){
         delete obj[key]
      }
   })
}

cleanObj([undefined, null], obj)

순수한 기능

const getObjWithoutVals = (dontReturnValsArr, obj) => {
    const cleanObj = {}
    Object.entries(obj).forEach( ([key, val]) => {
        if(!dontReturnValsArr.includes(val)){
            cleanObj[key]= val
        } 
    })
    return cleanObj
}

//To get a new object without `null` or `undefined` run: 
const nonEmptyObj = getObjWithoutVals([undefined, null], obj)

이것은 좋은, 아마도 한 줄, 솔루션
rekam

1

JSON.stringify 및 JSON.parse를 사용하여 객체에서 빈 속성을 제거 할 수 있습니다.

jsObject = JSON.parse(JSON.stringify(jsObject), (key, value) => {
               if (value == null || value == '' || value == [] || value == {})
                   return undefined;
               return value;
           });

이 트릭은 Obj가 JSON 직렬화 가능하다는 것을 보장하는 한 실제로 유효합니다. 그리고 그것은 또한 잘 작동합니다.
Polv

유효하지 않은 배열 및 객체 비교 ( {} != {}[] != []), 그렇지 않으면 접근 방식이 유효합니다
Aivaras

1

다음은 포괄적 인 재귀 함수 (원래 @chickens의 함수를 기반으로 함)입니다.

  • 당신이 말한 것을 재귀 적으로 제거하십시오. defaults=[undefined, null, '', NaN]
  • 일반 객체, 배열 및 Date 객체를 올바르게 처리
const cleanEmpty = function(obj, defaults = [undefined, null, NaN, '']) {
  if (!defaults.length) return obj
  if (defaults.includes(obj)) return

  if (Array.isArray(obj))
    return obj
      .map(v => v && typeof v === 'object' ? cleanEmpty(v, defaults) : v)
      .filter(v => !defaults.includes(v))

  return Object.entries(obj).length 
    ? Object.entries(obj)
        .map(([k, v]) => ([k, v && typeof v === 'object' ? cleanEmpty(v, defaults) : v]))
        .reduce((a, [k, v]) => (defaults.includes(v) ? a : { ...a, [k]: v}), {}) 
    : obj
}

용법:

// based off the recursive cleanEmpty function by @chickens. 
// This one can also handle Date objects correctly 
// and has a defaults list for values you want stripped.

const cleanEmpty = function(obj, defaults = [undefined, null, NaN, '']) {
  if (!defaults.length) return obj
  if (defaults.includes(obj)) return

  if (Array.isArray(obj))
    return obj
      .map(v => v && typeof v === 'object' ? cleanEmpty(v, defaults) : v)
      .filter(v => !defaults.includes(v))

  return Object.entries(obj).length 
    ? Object.entries(obj)
        .map(([k, v]) => ([k, v && typeof v === 'object' ? cleanEmpty(v, defaults) : v]))
        .reduce((a, [k, v]) => (defaults.includes(v) ? a : { ...a, [k]: v}), {}) 
    : obj
}


// testing

console.log('testing: undefined \n', cleanEmpty(undefined))
console.log('testing: null \n',cleanEmpty(null))
console.log('testing: NaN \n',cleanEmpty(NaN))
console.log('testing: empty string \n',cleanEmpty(''))
console.log('testing: empty array \n',cleanEmpty([]))
console.log('testing: date object \n',cleanEmpty(new Date(1589339052 * 1000)))
console.log('testing: nested empty arr \n',cleanEmpty({ 1: { 2 :null, 3: [] }}))
console.log('testing: comprehensive obj \n', cleanEmpty({
  a: 5,
  b: 0,
  c: undefined,
  d: {
    e: null,
    f: [{
      a: undefined,
      b: new Date(),
      c: ''
    }]
  },
  g: NaN,
  h: null
}))
console.log('testing: different defaults \n', cleanEmpty({
  a: 5,
  b: 0,
  c: undefined,
  d: {
    e: null,
    f: [{
      a: undefined,
      b: '',
      c: new Date()
    }]
  },
  g: [0, 1, 2, 3, 4],
  h: '',
}, [undefined, null]))


0

순수 / 기능적 접근 방식을 선호하는 경우

const stripUndef = obj => 
  Object.keys(obj)
   .reduce((p, c) => ({ ...p, ...(x[c] === undefined ? { } : { [c]: x[c] })}), {});
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.