如果值为null,undefined或empty,如何从对象和/或数组中删除属性?

时间:2017-03-20 17:53:38

标签: javascript

所以我有一个相当复杂的对象,如下所示:

var obj = {
    v1:"ok", 
    v2:[
        {av1:"foo",  av2:null}, // notice there's a null here
        {av1:"thing", av2:"stuff"}
    ], 
    v3: null, 
    v4:{
        ov1:"slim",
        ov2:"shady",
        ov3:null  // null
    }, 
    v5:[], // empty
    v6:{} // empty
}

我希望得到这个回复:

var obj = {
    v1:"ok", 
    v2:[{av1:"foo"},{av1:"thing", av2:"stuff"}], 
    v4:{ov1:"slim",ov2:"shady"}
}

我试图编写一个可以删除任何空,未定义或空的内容的函数,但它很快就会成为意大利面条的噩梦,并且不起作用。

我觉得这样做的方式更为优雅,但到目前为止,这是我的代码

function deleteNulls(o){
    for(let i in o){
        if(typeof o[i] == "Object"){
            o[i] = deleteNulls(o[i])
        }
        else if(typeof o[i] == "Array"){
            o[i] = deleteNulls(o[i])
        }
        if(o[i] == null || o[i] == "undefined" || o[i] == [] | o[i] == {})
            delete o[i]
        else {
            if(typeof o == "Object"){
                delete this.o[i]
                return o
            }
            else if (typeof o == "Array")
                return o.filter(k => o[k] != null)
        }
    }
    return o
}

var obj = deleteNulls(obj)

我对如何修复上述代码中的错误不感兴趣。如果我愿意,我可以让它工作,

我想知道是否有更简单的方法。

3 个答案:

答案 0 :(得分:2)

我建议使用像lodash这样的东西。对其速度和效率进行了测试和同行评审。

类似的东西:

var result = _.omitBy(my_object, _.isNil);

这将删除所有空值,您需要更改第二个参数以删除空对象和数组。

答案 1 :(得分:1)

它帮助我编写了这个解决方案,将逻辑拆分为递归clean函数(简化现有对象结构)和shouldKeep函数(告诉您是否可以从对象中完全删除键)基于其价值的结构)。

演示片段:

var object = {
  v1: "ok",
  v2: [{
      av1: "foo",
      av2: null
    }, // notice there's a null here
    {
      av1: "thing",
      av2: "stuff"
    }
  ],
  v3: null,
  v4: {
    ov1: "slim",
    ov2: "shady",
    ov3: null // null
  },
  v5: [], // empty
  v6: {} // empty
}

function shouldKeep (o) {
  if (Array.isArray(o)) {
    return o.length
  } else if (typeof o === 'object') {
    return o && Object.keys(o).length
  }
  return o != null
}


function clean (o) {
  if (Array.isArray(o)) {
    o.forEach(clean)
    var a = o.filter(shouldKeep)
    o.length = a.length
    for (var i = 0; i < a.length; i++) {
      o[i] = a[i]
    }
  } else if (o && typeof o === 'object') {
    Object.keys(o).forEach(function (k) {
      clean(o[k])
      if (!shouldKeep(o[k])) delete o[k]
    })
  }
  return o
}


console.log(clean(object))
.as-console-wrapper { min-height: 100vh; }

答案 2 :(得分:0)

这是我的看法。在大多数情况下都应该足够好。

 var object = {
      v1: "ok",
      v2: [{
          av1: "foo",
          av2: null
        }, // notice there's a null here
        {
          av1: "thing",
          av2: "stuff"
        }
      ],
      v3: null,
      v4: {
        ov1: "slim",
        ov2: "shady",
        ov3: null // null
      },
      v5: [], // empty
      v6: {} // empty
    }

   

    function isEmpty(v) {
      return v == undefined
      || v == null
      || (Array.isArray(v) && v.length === 0)
      || (typeof v === 'object' && Object.keys(v).length === 0)
    }
    
    function removeFalsyFromObject(v) {
      var keys = Object.keys(v);
      keys.forEach(function(k){
        var val = v[k];
        if (isEmpty(val)) {
          delete v[k];
        } else if (Array.isArray(val)) {
          removeFalsyFromArray(val);
        } else if (typeof val === 'object') {
          removeFalsyFromObject(val);
        }
      })
    }
    
    function removeFalsyFromArray(a) {
      for (var i=0; i<a.length; i++) {
        var v = a[i];
        if (isEmpty(v)) {
          a.splice(i,1);
          i--;
        } else if (Array.isArray(v)) {
          removeFalsyFromArray(v);
        } else if (typeof v === 'object') {
          removeFalsyFromObject(v);
        }
      }
    }
    
    function clean(obj) {
      removeFalsyFromObject(obj);
      return obj;
    }

    console.log(clean(object));