从嵌套对象(ES6)中删除空值和空值-清除嵌套对象

时间:2018-09-17 12:33:16

标签: javascript ecmascript-6

我有一个看起来像这样的对象:

{
    "a": "string not empty",
    "b": {
        "c": "string not empty",       
    },
    "d": {
        "e": false,
        "f": 0,
        "g": true,
        "h": 10
    },
    "i": {
        "j": 0,
        "k": null
    },
    "l": {
        "m": null
    },
    "n": {
        "o": 1,
        "p": "string (not empty)",
        "q": {}
    },
    "r": [],
    "l": "2000-01-01T01:01:00.000Z",
}

感谢此处提供的代码:https://stackoverflow.com/a/38364486/3912805现在可以删除嵌套对象的所有null值。

到目前为止,我已将此功能用于removeNull

removeNull = (obj) => {
  Object.keys(obj).forEach(key =>
    (obj[key] && typeof obj[key] === 'object') && removeNull(obj[key]) ||
    (obj[key] === undefined || obj[key] === null) && delete obj[key]
  );
  return obj;
};

但是我想增强此功能,以允许我删除嵌套对象中可能存在的所有空数组或任何空集合。

最终结果应为 klmqrl

{
    "a": "string not empty",
    "b": {
        "c": "string not empty",       
    },
    "d": {
        "e": false,
        "f": 0,
        "g": true,
        "h": 10
    },
    "i": {
        "j": 0
    },
    "n": {
        "o": 1,
        "p": "string (not empty)"
    },
    "l": "2000-01-01T01:01:00.000Z",
}

我需要保留所有设置为0false的值。

我想使用ES6方法来增强此removeNull的方法,但到目前为止我没有做到。

我还尝试了用于此How to deeply remove null values, empty objects and empty array from an object

的老式方法
itemToBool = item => {
  if (typeof item !== 'object' || item === null) return item;
  const cleanedItem = cleanObject(item);
  return Object.keys(cleanedItem).length !== 0 && cleanedItem;
};

cleanObject = obj => {
  if (Array.isArray(obj)) {
    const newArr = obj.map(itemToBool).filter(Boolean);
    return newArr.length && newArr;
  }
  const newObj = Object.entries(obj).reduce((a, [key, val]) => {
    const newVal = itemToBool(val);
    if (newVal !== null || newVal === false) a[key] = newVal;
    return a;
  }, {});
  return Object.keys(newObj).length > 0 && newObj;
};

但是它也失败了。

6 个答案:

答案 0 :(得分:3)

通过迭代对象的键/值对并首先迭代嵌套的可迭代对象,然后删除不需要的键,您可以采取一种直接的方法。

                InputStream input = this.getClass().getClassLoader().getResourceAsStream("com/moneydance/modules/features/securityquoteload/resources/stockexchanges.dict");
function clean(object) {
    Object
        .entries(object)
        .forEach(([k, v]) => {
            if (v && typeof v === 'object') {
                clean(v);
            }
            if (v && typeof v === 'object' && !Object.keys(v).length || v === null || v === undefined) {
                if (Array.isArray(object)) {
                    object.splice(k, 1);
                } else {
                    delete object[k];
                }
            }
        });
    return object;
}

var object = { a: "string not empty", b: { c: "string not empty" }, d: { e: false, f: 0, g: true, h: 10 }, i: { j: 0, k: null }, l: { m: null }, n: { o: 1, p: "string (not empty)", q: {} }, r: [{ foo: null }] };

console.log(clean(object));

答案 1 :(得分:2)

如果您不想变异对象并需要新的副本,则可以将对象字符串化为json并进行解析,然后在解析时进行过滤。如果不需要源对象,则可以将结果覆盖到相同的引用中。它可能不是性能有效的方法,但显然要更清洁,而不是自递归方法。

var obj = {
    "a": "string not empty",
    "b": {
        "c": "string not empty",       
    },
    "d": {
        "e": false,
        "f": 0,
        "g": true,
        "h": 10
    },
    "i": {
        "j": 0,
        "k": null
    },
    "l": {
        "m": null
    },
    "n": {
        "o": 1,
        "p": "string (not empty)",
        "q": {}
    },
    "r": [],
    "s": {"t": null},
    "u": [null, {"v": {}}]
}
function copyNonEmpty(o) {
  let ignores = [null, undefined, ""],
    isNonEmpty = d => !ignores.includes(d) && (typeof(d) !== "object" || Object.keys(d).length)
  return JSON.parse(JSON.stringify(o), function(k, v) {
    if (isNonEmpty(v))
      return v;
  });
}

var res = copyNonEmpty(obj);
console.log(JSON.stringify(res, null, 4));

如果值为ObjectArray,则typeof将返回object,而Object.keys将返回这两种情况的键数组({{1 }},"0", "1" ...(如果为数组),并且(键的)数组长度为0(如果为空数组或对象)。因此,有条件的话,它一定不能(2nullundefined)和(非"" OR object/array这是非空的,然后您可以获取该值。

答案 2 :(得分:0)

感谢Nina Scholz,我的增强版将是:

cleanObject = function(object) {
    Object
        .entries(object)
        .forEach(([k, v]) => {
            if (v && typeof v === 'object')
                cleanObject(v);
            if (v && 
                typeof v === 'object' && 
                !Object.keys(v).length || 
                v === null || 
                v === undefined ||
                v.length === 0
            ) {
                if (Array.isArray(object))
                    object.splice(k, 1);
                else if (!(v instanceof Date))
                    delete object[k];
            }
        });
    return object;
}

答案 3 :(得分:0)

您可以利用JSON.stringify及其第二个可选参数replacer,但是请注意,以下代码删除了null undefined

const sanitize = (obj) => {
  return JSON.parse(JSON.stringify(obj, (key, value) => {
    return (value === null ? undefined : value);
  }));
};

const obj = {
  "a": "string not empty",
  "b": {
    "c": "string not empty",
  },
  "d": {
    "e": false,
    "f": 0,
    "g": true,
    "h": 10
  },
  "i": {
    "j": 0,
    "k": null
  },
  "l": {
    "m": null
  },
  "n": {
    "o": 1,
    "p": "string (not empty)",
    "q": {}
  },
  "r": [],
  "l": "2000-01-01T01:01:00.000Z",
}

console.log(sanitize(obj))

答案 4 :(得分:0)

//sample Json Response
var items = {
            name: 'test',
            randomArray: [],
             randomObject: {
                id: null,
                someObject: {},
                someInternalArray: [],
                someUndefinedObject: undefined,
            },
              New name: null,
               nestedObject: [
                {
                      emp: {
                        id: null,
                    },
                   empAssets: 2,
                   joiningDate: {
                        startDate: null,
                        endDate: '2019/12/01',
                         Addresses: [],
                    },
                },
            ],
        };
       this.removeEmptyKeys(items);
        console.log('the final items ‘,items);

//Removing logic 
removeEmptyKeys(yourObject) {
        Object.keys(yourObject).forEach(key => {
            if (
                Object.prototype.toString.call(yourObject[key]) === '[object Date]' &&
                (yourObject[key].toString().length === 0 ||
                    yourObject[key].toString() === 'Invalid Date')
            ) {
                delete yourObject[key];
            } else if (yourObject[key] && typeof yourObject[key] === 'object') {
                this.removeEmptyKeysFromObject(yourObject[key]);
            } else if (yourObject[key] == null || yourObject[key] === '') {
                delete yourObject[key];
            }

            if (
                yourObject[key] &&
                typeof yourObject[key] === 'object' &&
                Object.keys(yourObject[key]).length === 0 &&
                Object.prototype.toString.call(yourObject[key]) !== '[object Date]'
            ) {
                delete yourObject[key];
            }
        });
        return yourObject;
    }

删除未定义,null,空字符串,空数组。如果有帮助,请投票。

答案 5 :(得分:0)

我按照以下方法试过

   const test = {
       a: '',
       b: 1,
       c: [],
       d: {
        e: null,
        f: 0,
        g: undefined,
        h: {
            i: 'test',
            j: {},
            k: '',
            l: {
                m: 'yo test',
                n: 'go for it'
            }
        }
     },
    e: 'yo tested'
    };

    const JS_PRIMITIVE_TYPES = { 'string': 1, 'number': 1, 'undefined': 1, 'boolean': 1, 
    'symbol': 1 }

    const isValuePrimitiveType = (value) => {
    const typeOfVal = typeof value;
    if (JS_PRIMITIVE_TYPES.hasOwnProperty(typeOfVal)) {
        return true;
    }
    return false;
    }

    /* MAIN Function which runs and call other functions
       allKeys : keys of object Object.keys(test);
       badJson : json which needs to be update
    */
      const iterateObjForRemoveEmptyElem = (badJson, allKeys) => {
       for (let index = 0; index < allKeys.length; index++) {
          const key = allKeys[index];
          if (isEmpty(badJson[key])) {
             delete badJson[key];
          } else if (Array.isArray(badJson[key]) || isValuePrimitiveType(badJson[key])) {
            continue;
         }
         else {
            const newKeys = Object.keys(badJson[key]);
            const newJson = Object.assign({}, badJson[key]);
            badJson[key] = iterateObjForRemoveEmptyElem(newJson, newKeys);
        }
    }
    return badJson;
    }



    const isEmpty = (val) => {
     if(val === '' || val === null || val === undefined ) {
         return true;
     } else if (Array.isArray(val) && val.length === 0){
        return true;
     } else if(typeof val === 'object' && Object.keys(val).length === 0){
        return true;
     }
    return false;
    }

    const myKeys = Object.keys(test);
    console.log("Final Result:::::",JSON.stringify(iterateObjForRemoveEmptyElem(test,myKeys)));

这对我有用到第 n 级