Удалить пустые атрибуты из объекта в Javascript - PullRequest
167 голосов
/ 13 ноября 2008

Как удалить все атрибуты undefined или null в объекте JavaScript?

(Вопрос похож на этот для массивов)

Ответы [ 29 ]

307 голосов
/ 13 июля 2016

Использование некоторых ES6 / ES2015 :

1) Простой однострочник для удаления элементов inline без присваивания:

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]);
    else if (obj[key] == null) delete obj[key];
  });
};

jsbin

4b) Это похоже на 4), но вместо непосредственного изменения исходного объекта возвращается новый объект.

const removeEmpty = (obj) => {
  const o = JSON.parse(JSON.stringify(obj)); // Clone source oect.

  Object.keys(o).forEach(key => {
    if (o[key] && typeof o[key] === 'object')
      o[key] = removeEmpty(o[key]);  // Recurse.
    else if (o[key] === undefined || o[key] === null)
      delete o[key]; // Delete undefined and null.
    else
      o[key] = o[key];  // Copy value.
  });

  return o; // Return new object.
};

5) функциональный подход к 4b), основанный на ответе @MichaelJ.Zoidl с использованием filter() и reduce(). Этот также возвращает новый объект:

const removeEmpty = (obj) =>
  Object.keys(obj)
    .filter(k => obj[k] !== null && obj[k] !== undefined)  // Remove undef. and null.
    .reduce((newObj, k) =>
      typeof obj[k] === 'object' ?
        Object.assign(newObj, {[k]: removeEmpty(obj[k])}) :  // Recurse.
        Object.assign(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]
})

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

131 голосов
/ 13 ноября 2008

Вы можете пройти через объект:

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

Если вас беспокоит, что удаление этого свойства не запускает цепочку типов объектов, вы также можете:

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

Несколько замечаний о нуле против неопределенных:

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

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

test.notaprop === undefined; // true
test.notaprop == undefined; // true
76 голосов
/ 08 марта 2016

Если вы используете lodash или underscore.js, вот простое решение:

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

var compacted = _.pickBy(obj);

Это будет работать только с lodash 4, pre lodash 4 или underscore.js, используйте _.pick(obj, _.identity);

34 голосов
/ 12 июня 2014

Если кому-то нужна рекурсивная версия ответа Оуэна (и Эрика), вот он:

/**
 * 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);
        }
    }
}
15 голосов
/ 22 мая 2015

JSON.stringify удаляет неопределенные ключи.

removeUndefined = function(json){
  return JSON.parse(JSON.stringify(json))
}
13 голосов
/ 13 ноября 2008

Возможно, вы ищете ключевое слово delete.

var obj = { };
obj.theProperty = 1;
delete obj.theProperty;
7 голосов
/ 10 ноября 2016

Вы можете использовать комбинацию 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

6 голосов
/ 17 мая 2017

Самое простое из возможных решений Lodash для возврата объекта с отфильтрованными значениями null и undefined.

_.omitBy(obj, _.isNil)

5 голосов
/ 26 апреля 2017

Короче чистое решение 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

5 голосов
/ 28 ноября 2016

Используя 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...