2008-11-13 5 views
89

Как удалить все атрибуты, которые являются undefined или null в объекте JavaScript?Удалить пустые атрибуты из объекта в Javascript

(Вопрос похож на this one для Массивы)

+8

настоятельно рекомендуем люди игнорируют топ-ранга и перейти к версии/ES7 ES6 здесь, http://stackoverflow.com/a/38340730/124486 – 2016-12-13 07:54:03

ответ

87

Вы можете цикл через объект:

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 цепи объекта, вы также можете:

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 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» переменная будет протекать во внешнюю область, если этот фрагмент когда-либо использовался в функции. – 2013-12-16 06:11:46

+4

вы можете упростить (test [i] === null || test [i] === undefined) to (test [i] == null) – jaf0 2015-05-24 03:01:53

+0

Привет, @EricNguyen, в отличие от C и других нескольких языков, javascript делает * not * имеют область видимости блока для переменных (только область функций), поэтому переменная _i_ всегда будет втекать в область после блока _for_. – 2016-05-10 09:54:52

12

Вы, вероятно, ищете delete ключевое слово.

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

Это то, что он делает выше, это также все еще оставляет неопределенным в объекте , – 2014-07-24 15:54:36

-1

Простой способ выполнить эту задачу. Это выполняется с использованием метода jQuery $.grep.

var test = { 
    a: null, 
    b: 'hello world', 
    c: 12345 
} 

var newTest = $.grep(
         test, 
         function(element, index) { 
         return (test[element] && test[element] != null); 
         } 
        ); 
// newTest = { b: 'hello world', c: 12345 } 

$.grep находит элементы массива, которые удовлетворяют фильтр function.In этого случая, любой атрибут, который не является нулевым

+1

не тестирует объект, а не массив здесь? – vincentlcy 2013-06-25 05:11:55

+1

в этом вопросе нет тега jquery – iguider 2014-08-29 20:30:28

2

вы можете сделать короче с ! условием

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

Оставаться в использование: as @semicolor объявить в комментариях: Это также приведет к удалению свойств, если значение представляет собой пустую строку, false или ноль

31

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

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

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

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

Эта функция может очистить пустой объект после удаления invitival emptys внутри объекта или массива. это гарантирует, что у вас нет пустого массива или объекта, висящего вокруг.

function removeNullsInObject(obj) { 
      if(typeof obj === 'string' || obj === ""){ 
       return; 
      } 
      $.each(obj, function(key, value){ 
       if (value === "" || value === null){ 
        delete obj[key]; 
       } else if ($.isArray(value)) { 
        if(value.length === 0){ 
         delete obj[key]; 
         return; 
        } 
        $.each(value, function (k,v) { 
         removeNullsInObject(v); 
        }); 
        if(value.length === 0){ 
         delete obj[key]; 
        } 
       } else if (typeof value === 'object') { 
        if(Object.keys(value).length === 0){ 
         delete obj[key]; 
         return; 
        } 
        removeNullsInObject(value); 
        if(Object.keys(value).length === 0){ 
         delete obj[key]; 
        } 
       } 
      }); 
} 
2

Для глубокого поиска я использовал следующий код, может быть, это будет полезно для тех, кто смотрит на этот вопрос (он не может использоваться для циклических зависимостей):

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

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

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

var compacted = _.pickBy(obj); 

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

2

Чтобы piggypack на Ben's answer о том, как решить эту проблему с помощью lodash-х _.pickBy, вы можете решить эту проблему в библиотеке сестры: Underscore.js «s _.pick.

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

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

См: JSFiddle Example

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

Использование некоторых 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]); 
    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's answer с помощью 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/2016Object.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

5

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

0

Ниже раствора удаляет null, а также empty object
empty object или {} остаточная вследствие null очистки

Чтобы очистить объект использовать ниже

/** 
* 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 || test[i] === undefined) { 
     delete test[i]; 
    } 
    // recurse for array and object 
    else if (recurse && typeof test[i] === 'object') { 
     test[i] = delete_null_properties(test[i], recurse); 
    } 
    if((test[i] && typeof(test[i]) === 'object') && 
     (Object.keys(test[i]).length === 0 || test[i] == [{}])) { 
     // delete the child property if its empty 
     delete test[i] 
    } 
    if(test == {}){ 
     // delete empty 'parent' object when there is a residue due to deletion 
     // of its child properties 
     delete test 
    } else if(test instanceof Array && test[i] == undefined) { 
     // in the case of array removed null childs by splicing it off 
     test.splice(i,1) 
     // however if the parent array itself goes empty remove it off 
     if(test instanceof Array && test.length == 0) { 
     test = null 
     } 
    }  
    } 
    return test 
} 

delete_null_properties(obj, true) 
0

С Lodash:

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

Если вы не хотите, чтобы мутировать в месте, но возвращать клон с нулевым/неопределенными удалены, вы можете использовать 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; 
    }, {}); 
} 
2

Вместо удаления свойства вы также можете создать новый объект с ключами, которые не являются нулевыми.

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

Сокращенное решение ES6, преобразование его в массив, использование функции фильтра и преобразование его обратно в объект. Было бы также легко сделать функцию ...

КПП. с этим .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

1

Простейшее возможное решение Lodash вернуть объект с null и undefined значений отфильтрованы.

_.omitBy(obj, _.isNil)

0

Вы можете использовать этот object-clean component для очищает falsy свойства всего объекта и возвращает новый объект без них.

Примеры:

new cleaned object 

clean({ foo: null, bar: 'foo' }) // => { bar: 'foo' } 
1

Если вы используете eslint и хотите, чтобы избежать отключения в не-парам-Переприсвоить правило, вы можете использовать Object.assign в сочетании с.уменьшить и имя вычисленного свойства для довольно элегантного решения 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

Если вы хотите 4 линии чистого раствора ES7:

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

Это сохранит булевские значения, и оно также очистит массивы. Он также сохраняет исходный объект, возвращая очищенную копию.

0

У меня такой же сценарий в моем проекте и достигается с использованием следующего метода.

Он работает со всеми типами данных, несколько упомянутых выше не работают с датой и пустыми массивами.

removeEmptyKeysFromObject.js

removeEmptyKeysFromObject(obj) { 
 
    Object.keys(obj).forEach(key => { 
 
    if (Object.prototype.toString.call(obj[key])  ===  '[object Date]' && obj[key].toString().length === 0) { 
 
     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()

Смежные вопросы