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), {})

필터 null및 undefined값 :

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)), {})

재귀 솔루션 : 필터null 및undefined

객체의 경우 :

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당신이에 대해 확인합니다 undefined및 null.
— 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
교체 기능 null을 undefined사용하는 것으로 취급 되어야 하는 경우 자세한 내용은 다음 답변을 참조하십시오. 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)). 질문 undefined과 null가치 에 관한 것이 었습니다 .
— mayid

13

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

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

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

10

null및 undefined값이 필터링 된 객체를 반환하는 가장 간단한 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, undefined및 false값 :

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] === undefined에obj[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.