source

Javascript에서 개체에서 빈 특성 제거

gigabyte 2022. 11. 28. 21:13
반응형

Javascript에서 개체에서 빈 특성 제거

의 하려면 어떻게 합니까?undefined ""nullJavaScript?

(어레이에 관한 질문도 이와 유사합니다.

ES10/ES2019 예시

심플한 원라이너(새로운 오브젝트를 되돌림).

let o = Object.fromEntries(Object.entries(obj).filter(([_, v]) => v != null));

위와 같으나 함수로 작성되었습니다.

function removeEmpty(obj) {
  return Object.fromEntries(Object.entries(obj).filter(([_, v]) => v != null));
}

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

function removeEmpty(obj) {
  return Object.fromEntries(
    Object.entries(obj)
      .filter(([_, v]) => v != null)
      .map(([k, v]) => [k, v === Object(v) ? removeEmpty(v) : v])
  );
}

ES6/ES2015 예시

심플한 원라이너경고:그러면 새 개체가 반환되지 않고 지정된 개체가 변환됩니다.

Object.keys(obj).forEach((k) => obj[k] == null && delete obj[k]);

단일 선언(지정된 개체를 변환하지 않음).

let o = Object.keys(obj)
  .filter((k) => obj[k] != null)
  .reduce((a, k) => ({ ...a, [k]: obj[k] }), {});

위와 같으나 함수로 작성되었습니다.

function removeEmpty(obj) {
  return Object.entries(obj)
    .filter(([_, v]) => v != null)
    .reduce((acc, [k, v]) => ({ ...acc, [k]: v }), {});
}

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

function removeEmpty(obj) {
  return Object.entries(obj)
    .filter(([_, v]) => v != null)
    .reduce(
      (acc, [k, v]) => ({ ...acc, [k]: v === Object(v) ? removeEmpty(v) : v }),
      {}
    );
}

위의 기능과 동일하지만 명령형(비기능형)으로 작성됩니다.

function removeEmpty(obj) {
  const newObj = {};
  Object.entries(obj).forEach(([k, v]) => {
    if (v === Object(v)) {
      newObj[k] = removeEmpty(v);
    } else if (v != null) {
      newObj[k] = obj[k];
    }
  });
  return newObj;
}

ES5/ES2009 예시

옛날에는 일이 훨씬 더 장황했다.

기능적인 스타일로 작성된 비재귀 버전입니다.

function removeEmpty(obj) {
  return Object.keys(obj)
    .filter(function (k) {
      return obj[k] != null;
    })
    .reduce(function (acc, k) {
      acc[k] = obj[k];
      return acc;
    }, {});
}

이것은 명령형으로 작성된 비재귀 버전입니다.

function removeEmpty(obj) {
  const newObj = {};
  Object.keys(obj).forEach(function (k) {
    if (obj[k] && typeof obj[k] === "object") {
      newObj[k] = removeEmpty(obj[k]);
    } else if (obj[k] != null) {
      newObj[k] = obj[k];
    }
  });
  return newObj;
}

그리고 기능적인 스타일로 쓰여진 재귀적인 버전입니다.

function removeEmpty(obj) {
  return Object.keys(obj)
    .filter(function (k) {
      return obj[k] != null;
    })
    .reduce(function (acc, k) {
      acc[k] = typeof obj[k] === "object" ? removeEmpty(obj[k]) : obj[k];
      return acc;
    }, {});
}

오브젝트를 루프할 수 있습니다.

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];
    }
  }
  return obj
}

console.log(test);
console.log(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 vs 정의되지 않음에 대한 몇 가지 참고 사항:

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

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

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

ES6+용 최단 라이너 1대

false 값 ('false')"",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)), {});
  } 
}

lodash 또는 underscore.js를 사용하는 경우 다음과 같은 간단한 솔루션이 있습니다.

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

var compacted = _.pickBy(obj);

4, 4 합니다.lodash 4, pre lodash 4 underscore.js ad를 사용합니다._.pick(obj, _.identity);

오웬의 (그리고 에릭의) 답변을 재귀적으로 듣고 싶은 사람은 다음과 같습니다.

/**
 * 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);
        }
    }
}

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

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

'어울리다'를 할 수 요.JSON.stringify그 파라미터 , " " " " " 입니다.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의 예

Lodash를 .null ★★★★★★★★★★★★★★★★★」undefined값이 필터링되었습니다.

_.omitBy(obj, _.isNil)

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

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

사용방법:

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

Emmanuel의 설명에서 설명한 바와 같이, 이 기술은 데이터 구조에 JSON 형식(문자열, 숫자, 목록 등)으로 지정할 수 있는 데이터 유형만 포함하는 경우에만 작동합니다.

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

당신은 아마 키워드를 찾고 있을 거예요.

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

요.! 설정

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

사용방법: @semicolor anouncement in comment:값이 빈 문자열(false 또는 0)인 경우에도 속성이 삭제됩니다.

null 및 정의되지 않은 모든 속성 제거

let obj = {
"id": 1,
"firstName": null,
"lastName": null,
"address": undefined,
"role": "customer",
"photo": "fb79fd5d-06c9-4097-8fdc-6cebf73fab26/fc8efe82-2af4-4c81-bde7-8d2f9dd7994a.jpg",
"location": null,
"idNumber": null,
};

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

나는 내 프로젝트에서 같은 시나리오를 가지고 있으며 다음과 같은 방법으로 달성했습니다.

모든 데이터 타입에서 동작합니다.상기의 데이터 타입에서는, 날짜나 빈 어레이에 대응하지 않는 것은 거의 없습니다.

Remove Empty Keys From Object.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;
}

이 함수에 임의의 개체를 전달합니다.remove Empty Keys From Object()

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)

ES6 순수 솔루션을 단축하여 어레이로 변환하고 필터 기능을 사용하여 개체로 다시 변환합니다.기능을 만드는 것도 쉬울 텐데...

이 this b.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빈 https://jsbin.com/kugoyinora/edit?js,console

즉 기능적이고 불변한 접근법,.filter 필요

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

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

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

상세한 검색에서는, 다음의 코드를 사용하고 있습니다.이 질문을 참조하는 사람에게는 도움이 될 수 있습니다(순환 의존관계에는 사용할 수 없습니다).

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;
    }

순수 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;
}

이렇게 하면 부울 값이 유지되고 어레이도 정리됩니다.또한 정리된 복사본을 반환하여 원래 개체를 보존합니다.

(유형체크 없이) 리셋 도우미가 기능을 발휘합니다.

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

다음은 포괄적인 재귀 함수(원래는 @chickens의 함수에 기초함)입니다.

  • 으로 이 말한 defaults=[undefined, null, '', NaN]
  • 일반 객체, 어레이 및 날짜 객체를 올바르게 처리
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]))

변환하지 않고 null/정의되지 않은 클론을 반환하는 경우 ES6 축소 기능을 사용할 수 있습니다.

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

Lodash를 사용하여 이 문제를 해결하는 방법에 대한 벤의 답변을 바탕으로 돼지 포장을 하기 위해_.pickBy자매 라이브러리에서도 이 문제를 해결할 수 있습니다.언더스코어.js의_.pick.

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

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

참조: JSFiddle의 예

여기 대안이 있습니다.

타이프스크립트:

function objectDefined <T>(obj: T): T {
  const acc: Partial<T> = {};
  for (const key in obj) {
    if (obj[key] !== undefined) acc[key] = obj[key];
  }
  return acc as T;
}

Javascript:

function objectDefined(obj) {
  const acc = {};
  for (const key in obj) {
    if (obj[key] !== undefined) acc[key] = obj[key];
  }
  return acc;
}

를 사용할 수도 있습니다....를 사용하여 구문 확산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);

제거할 필요가 있는 경우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;
  }, {});
}

Lodash의 경우:

_.omitBy({a: 1, b: null}, (v) => !v)

eslint를 사용하여 no-param-reassign 규칙의 트립을 방지하려면 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 }

다음으로 기능적으로 제거할 수 있는 방법을 제시하겠습니다.nullsES6를 사용하여 오브젝트를 변환하지 않고 오브젝트에서만reduce:

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

null, 미정의, 빈 객체 및 빈 어레이를 반복적으로 삭제하고 복사본을 반환한다(ES6 버전).

export function skipEmpties(dirty) {
    let item;
    if (Array.isArray(dirty)) {
        item = dirty.map(x => skipEmpties(x)).filter(value => value !== undefined);
        return item.length ? item : undefined;
    } else if (dirty && typeof dirty === 'object') {
        item = {};
        Object.keys(dirty).forEach(key => {
            const value = skipEmpties(dirty[key]);
            if (value !== undefined) {
                item[key] = value;
            }
        });
        return Object.keys(item).length ? item : undefined;
    } else {
        return dirty === null ? undefined : dirty;
    }
}

언급URL : https://stackoverflow.com/questions/286141/remove-blank-attributes-from-an-object-in-javascript

반응형