简体   繁体   English

从JavaScript对象中递归删除空值

[英]Recursively remove null values from JavaScript object

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. 我有一个JSON obj,经过一些操作(比如删除一些部分),我打印它,一切看起来都不错,除了我有一些null值。 How do I remove these? 我该如何删除这些?

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个null值):

{
    "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
        }
    }
}

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! 希望能帮助到你!

// 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: 如果要从对象和数组中递归删除所有null值:

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

Fixing your book array is easy enough - you just have to filter out the nulls. 修复你的book数组很容易 - 你只需要过滤掉空值。 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). 我确信还有很多其他方法,比如使用jQuery或filter功能(我认为在旧版浏览器中不可用)。 You could also loop through the array and splice out the nulls. 您也可以循环遍历数组并splice出空值。 I just find this way the easiest to read. 我发现这种方式最容易阅读。

The following is a modification to the answer by @Phrogz. 以下是@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. 如果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;
}

How do you deletes your pieces ? 你怎么删除你的作品?

Delete an array element with the delete operator leaves a hole in the array. 使用delete运算符删除数组元素会在数组中留下一个空洞。 Instead, you should use Array.splice which can remove properly an element from array. 相反,您应该使用Array.splice ,它可以正确地从数组中删除元素。

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

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) 您需要修改代码以使用对象(或使用对象内部的代码)

We can use JSON.stringify and JSON.parse together to recursively remove blank attributes from an object. 我们可以一起使用JSON.stringify和JSON.parse以递归方式从对象中删除空白属性。

jsObject = JSON.parse(JSON.stringify(jsObject), (key, value) => {
               if (value == null || value == '' || value == [] || value == {})
                   return undefined;
               return value;
           });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM