从JavaScript对象中递归删除空值

时间:2022-10-27 09:50:50

I have a JSON obj, after some operations (like delete some pieces), I print it and everything looks good except that I have some null values. How do I remove these?

我有一个JSON obj,经过一些操作(比如删除一些部分),我打印它,一切看起来都很好,除了我有一些空值。我该如何删除这些?

I use JSON.stringify(obj, null, 2) method to print, and here is what it looks like:

我使用JSON.stringify(obj,null,2)方法进行打印,这是它的样子:

{
    "store": {
        "book": [
             null,
             {
                 "category": "fiction",
                 "author": "Evelyn Waugh",
                 "title": "Sword of Honour",
                 "price": 12.99
             },
             null,
             {
                  "category": "fiction",
                  "author": "J. R. R. Tolkien",
                  "title": "The Lord of the Rings",
                  "isbn": "0-395-19395-8",
                  "price": 22.99
             }
        ],
        "bicycle": {
             "color": "red",
             null,
             "price": 19.95
        }
    }
}

I want it to be much compact and pretty clean(remove the extra 3 null values):

我希望它非常紧凑,非常干净(删除额外的3个空值):

{
    "store": {
        "book": [
             {
                 "category": "fiction",
                 "author": "Evelyn Waugh",
                 "title": "Sword of Honour",
                 "price": 12.99
             },
             {
                  "category": "fiction",
                  "author": "J. R. R. Tolkien",
                  "title": "The Lord of the Rings",
                  "isbn": "0-395-19395-8",
                  "price": 22.99
             }
        ],
        "bicycle": {
             "color": "red",
             "price": 19.95
        }
    }
}

7 个解决方案

#1


34  

I had to solve a similar problem, however I wanted to remove not only null values but also undefined, NaN, empty String, empty array and empty object values, recursively, by inspecting nested objects and also nested arrays.

我不得不解决类似的问题,但是我想通过检查嵌套对象和嵌套数组,不仅要删除空值,还要删除未定义,NaN,空字符串,空数组和空对象值。

The following function is using Lo-Dash:

以下函数使用Lo-Dash:

function pruneEmpty(obj) {
  return function prune(current) {
    _.forOwn(current, function (value, key) {
      if (_.isUndefined(value) || _.isNull(value) || _.isNaN(value) ||
        (_.isString(value) && _.isEmpty(value)) ||
        (_.isObject(value) && _.isEmpty(prune(value)))) {

        delete current[key];
      }
    });
    // remove any leftover undefined values from the delete 
    // operation on an array
    if (_.isArray(current)) _.pull(current, undefined);

    return current;

  }(_.cloneDeep(obj));  // Do not modify the original object, create a clone instead
}

For example, if you invoke the method with the following input object:

例如,如果使用以下输入对象调用该方法:

var dirty = {
  key1: 'AAA',
  key2: {
    key21: 'BBB'
  },
  key3: {
    key31: true,
    key32: false
  },
  key4: {
    key41: undefined,
    key42: null,
    key43: [],
    key44: {},
    key45: {
      key451: NaN,
      key452: {
        key4521: {}
      },
      key453: [ {foo: {}, bar:''}, NaN, null, undefined ]
    },
    key46: ''
  },
  key5: {
    key51: 1,
    key52: '  ',
    key53: [1, '2', {}, []],
    key54: [{ foo: { bar: true, baz: null }}, { foo: { bar: '', baz: 0 }}]
  },
  key6: function () {}
};

It'll recursively discard all the "bad" values, keeping in the end only the ones that carry some information.

它将以递归方式丢弃所有“坏”值,最后只保留带有某些信息的值。

var clean = pruneEmpty(dirty);
console.log(JSON.stringify(clean, null, 2));

{
  key1: 'AAA',
  key2: {
    key21: 'BBB'
  },
  key3: {
    key31: true,
    key32: false
  },
  key5: {
    key51: 1,
    key52: '  ',
    key53: [1, '2'],
    key54: [{ foo: { bar: true }}, { foo: { baz: 0 }}]
  }
};

Hope it helps!

希望能帮助到你!

#2


11  

// Iterate the array from back to front, removing null entries
for (var i=obj.store.book.length;i--;){
  if (obj.store.book[i]===null) obj.store.book.splice(i,1);
}

If you want to remove all null values recursively from both objects and arrays:

如果要从对象和数组中递归删除所有空值:

// Compact arrays with null entries; delete keys from objects with null value
function removeNulls(obj){
  var isArray = obj instanceof Array;
  for (var k in obj){
    if (obj[k]===null) isArray ? obj.splice(k,1) : delete obj[k];
    else if (typeof obj[k]=="object") removeNulls(obj[k]);
  }
}

Seen in action:

看到行动:

var o = {
  "store": {
    "book": [
       null,
       {
         "category": "fiction",
         "author": "Evelyn Waugh",
         "title": "Sword of Honour",
         "price": 12.99
       },
       null,
       {
          "category": "fiction",
          "author": "J. R. R. Tolkien",
          "title": "The Lord of the Rings",
          "isbn": "0-395-19395-8",
          "price": 22.99
       }
    ],
    "bicycle": {
       "color": "red",
       "bad": null,
       "price": 19.95
    }
  }
}

removeNulls(o);

console.log(JSON.stringify(o,null,2));
// {
//   "store": {
//     "book": [
//       {
//         "category": "fiction",
//         "author": "Evelyn Waugh",
//         "title": "Sword of Honour",
//         "price": 12.99
//       },
//       {
//         "category": "fiction",
//         "author": "J. R. R. Tolkien",
//         "title": "The Lord of the Rings",
//         "isbn": "0-395-19395-8",
//         "price": 22.99
//       }
//     ],
//     "bicycle": {
//       "color": "red",
//       "price": 19.95
//     }
//   }
// }

#3


4  

Fixing your book array is easy enough - you just have to filter out the nulls. The most straightforward way would probably be building a new array and reassigning it:

修复你的书籍数组很容易 - 你只需要过滤掉空值。最直接的方法可能是构建一个新阵列并重新分配它:

var temp = [];
var i;
for (i = 0; i < obj.store.book.length; ++i) {
    if (obj.store.book[i] != null) {
        temp.push(obj.store.book[i]);
    }
}
obj.store.book = temp;

I'm sure there are plenty of other ways, like using jQuery, or the filter function (which I believe is not available in older browsers). You could also loop through the array and splice out the nulls. I just find this way the easiest to read.

我确信还有很多其他方法,比如使用jQuery或过滤器功能(我认为在旧版浏览器中不可用)。您还可以循环遍历数组并拼接出空值。我发现这种方式最容易阅读。

#4


2  

The following is a modification to the answer by @Phrogz. If book[3] was also null, the answer given would not remove the last null because the array's length would be less than k in last loop's iteration.

以下是@Phrogz对答案的修改。如果book [3]也为null,则给出的答案不会删除最后一个null,因为在最后一个循环的迭代中数组的长度将小于k。

The following would work by performing a second call to the array:

以下将通过执行第二次调用数组来工作:

function removeNulls(obj) {
  var isArray = obj instanceof Array;
  for (var k in obj) {
    if (obj[k] === null) isArray ? obj.splice(k, 1) : delete obj[k];
    else if (typeof obj[k] == "object") removeNulls(obj[k]);
    if (isArray && obj.length == k) removeNulls(obj);
  }
  return obj;
}

#5


1  

How do you deletes your pieces ?

你怎么删除你的作品?

Delete an array element with the delete operator leaves a hole in the array. Instead, you should use Array.splice which can remove properly an element from array.

使用delete运算符删除数组元素会在数组中留下一个空洞。相反,您应该使用Array.splice,它可以正确地从数组中删除元素。

#6


0  

I use the code here

我在这里使用代码

Remove empty elements from an array in Javascript

在Javascript中从数组中删除空元素

then you could call it like

然后你可以称之为

JSON.stringify(obj.clean(null), null, 2)

JSON.stringify(obj.clean(null),null,2)

You would need to modify the code to work with objects too (or use the code as is inside the objects)

您需要修改代码以使用对象(或使用对象内部的代码)

#7


0  

Please use this npm package

请使用此npm包

npm i --save nnjson
var nnjson = require('nnjson');
user = {
  a: null,
  b: 'hello',
  c: {
    c1: 'world',
    c2: null
  }
}
var newUser = nnjson.removeNull(user);
console.log (newUser)

result

结果

{
  b: 'hello',
  c: {
    c1: 'world'
  }
}

#1


34  

I had to solve a similar problem, however I wanted to remove not only null values but also undefined, NaN, empty String, empty array and empty object values, recursively, by inspecting nested objects and also nested arrays.

我不得不解决类似的问题,但是我想通过检查嵌套对象和嵌套数组,不仅要删除空值,还要删除未定义,NaN,空字符串,空数组和空对象值。

The following function is using Lo-Dash:

以下函数使用Lo-Dash:

function pruneEmpty(obj) {
  return function prune(current) {
    _.forOwn(current, function (value, key) {
      if (_.isUndefined(value) || _.isNull(value) || _.isNaN(value) ||
        (_.isString(value) && _.isEmpty(value)) ||
        (_.isObject(value) && _.isEmpty(prune(value)))) {

        delete current[key];
      }
    });
    // remove any leftover undefined values from the delete 
    // operation on an array
    if (_.isArray(current)) _.pull(current, undefined);

    return current;

  }(_.cloneDeep(obj));  // Do not modify the original object, create a clone instead
}

For example, if you invoke the method with the following input object:

例如,如果使用以下输入对象调用该方法:

var dirty = {
  key1: 'AAA',
  key2: {
    key21: 'BBB'
  },
  key3: {
    key31: true,
    key32: false
  },
  key4: {
    key41: undefined,
    key42: null,
    key43: [],
    key44: {},
    key45: {
      key451: NaN,
      key452: {
        key4521: {}
      },
      key453: [ {foo: {}, bar:''}, NaN, null, undefined ]
    },
    key46: ''
  },
  key5: {
    key51: 1,
    key52: '  ',
    key53: [1, '2', {}, []],
    key54: [{ foo: { bar: true, baz: null }}, { foo: { bar: '', baz: 0 }}]
  },
  key6: function () {}
};

It'll recursively discard all the "bad" values, keeping in the end only the ones that carry some information.

它将以递归方式丢弃所有“坏”值,最后只保留带有某些信息的值。

var clean = pruneEmpty(dirty);
console.log(JSON.stringify(clean, null, 2));

{
  key1: 'AAA',
  key2: {
    key21: 'BBB'
  },
  key3: {
    key31: true,
    key32: false
  },
  key5: {
    key51: 1,
    key52: '  ',
    key53: [1, '2'],
    key54: [{ foo: { bar: true }}, { foo: { baz: 0 }}]
  }
};

Hope it helps!

希望能帮助到你!

#2


11  

// Iterate the array from back to front, removing null entries
for (var i=obj.store.book.length;i--;){
  if (obj.store.book[i]===null) obj.store.book.splice(i,1);
}

If you want to remove all null values recursively from both objects and arrays:

如果要从对象和数组中递归删除所有空值:

// Compact arrays with null entries; delete keys from objects with null value
function removeNulls(obj){
  var isArray = obj instanceof Array;
  for (var k in obj){
    if (obj[k]===null) isArray ? obj.splice(k,1) : delete obj[k];
    else if (typeof obj[k]=="object") removeNulls(obj[k]);
  }
}

Seen in action:

看到行动:

var o = {
  "store": {
    "book": [
       null,
       {
         "category": "fiction",
         "author": "Evelyn Waugh",
         "title": "Sword of Honour",
         "price": 12.99
       },
       null,
       {
          "category": "fiction",
          "author": "J. R. R. Tolkien",
          "title": "The Lord of the Rings",
          "isbn": "0-395-19395-8",
          "price": 22.99
       }
    ],
    "bicycle": {
       "color": "red",
       "bad": null,
       "price": 19.95
    }
  }
}

removeNulls(o);

console.log(JSON.stringify(o,null,2));
// {
//   "store": {
//     "book": [
//       {
//         "category": "fiction",
//         "author": "Evelyn Waugh",
//         "title": "Sword of Honour",
//         "price": 12.99
//       },
//       {
//         "category": "fiction",
//         "author": "J. R. R. Tolkien",
//         "title": "The Lord of the Rings",
//         "isbn": "0-395-19395-8",
//         "price": 22.99
//       }
//     ],
//     "bicycle": {
//       "color": "red",
//       "price": 19.95
//     }
//   }
// }

#3


4  

Fixing your book array is easy enough - you just have to filter out the nulls. The most straightforward way would probably be building a new array and reassigning it:

修复你的书籍数组很容易 - 你只需要过滤掉空值。最直接的方法可能是构建一个新阵列并重新分配它:

var temp = [];
var i;
for (i = 0; i < obj.store.book.length; ++i) {
    if (obj.store.book[i] != null) {
        temp.push(obj.store.book[i]);
    }
}
obj.store.book = temp;

I'm sure there are plenty of other ways, like using jQuery, or the filter function (which I believe is not available in older browsers). You could also loop through the array and splice out the nulls. I just find this way the easiest to read.

我确信还有很多其他方法,比如使用jQuery或过滤器功能(我认为在旧版浏览器中不可用)。您还可以循环遍历数组并拼接出空值。我发现这种方式最容易阅读。

#4


2  

The following is a modification to the answer by @Phrogz. If book[3] was also null, the answer given would not remove the last null because the array's length would be less than k in last loop's iteration.

以下是@Phrogz对答案的修改。如果book [3]也为null,则给出的答案不会删除最后一个null,因为在最后一个循环的迭代中数组的长度将小于k。

The following would work by performing a second call to the array:

以下将通过执行第二次调用数组来工作:

function removeNulls(obj) {
  var isArray = obj instanceof Array;
  for (var k in obj) {
    if (obj[k] === null) isArray ? obj.splice(k, 1) : delete obj[k];
    else if (typeof obj[k] == "object") removeNulls(obj[k]);
    if (isArray && obj.length == k) removeNulls(obj);
  }
  return obj;
}

#5


1  

How do you deletes your pieces ?

你怎么删除你的作品?

Delete an array element with the delete operator leaves a hole in the array. Instead, you should use Array.splice which can remove properly an element from array.

使用delete运算符删除数组元素会在数组中留下一个空洞。相反,您应该使用Array.splice,它可以正确地从数组中删除元素。

#6


0  

I use the code here

我在这里使用代码

Remove empty elements from an array in Javascript

在Javascript中从数组中删除空元素

then you could call it like

然后你可以称之为

JSON.stringify(obj.clean(null), null, 2)

JSON.stringify(obj.clean(null),null,2)

You would need to modify the code to work with objects too (or use the code as is inside the objects)

您需要修改代码以使用对象(或使用对象内部的代码)

#7


0  

Please use this npm package

请使用此npm包

npm i --save nnjson
var nnjson = require('nnjson');
user = {
  a: null,
  b: 'hello',
  c: {
    c1: 'world',
    c2: null
  }
}
var newUser = nnjson.removeNull(user);
console.log (newUser)

result

结果

{
  b: 'hello',
  c: {
    c1: 'world'
  }
}