繁体   English   中英

从 JavaScript 对象中递归删除空值

[英]Recursively remove nullish values from a JavaScript object

我搜索了这个,但找不到满意的答案,所以我在这里发布我自己的答案。

基本上我想要一个函数:

  • 将一个对象作为它的参数
  • 递归删除值为nullundefined[]{}''属性
  • 保留0false
  • 返回一个删除了这些属性的新对象
  • 最好是没有突变的功能风格

您可以将三种类型的数据分开

  • 大批,
  • 目的
  • 原始值

并通过减少复杂数据类型和检查原始值来获得想要的子集。

 const isNullish = x => [ v => v === '', v => v === null, v => v === undefined, v => v && typeof v === 'object' && !Object.keys(v).length ].some(f => f(x)), getArray = array => { var temp = array.reduce((r, v) => { v = getNotNullish(v); if (v !== undefined) r.push(v); return r; }, []); return temp.length ? temp : undefined; }, getObject = object => { var hasValues = false, temp = Object.entries(object).reduce((r, [k, v]) => { v = getNotNullish(v); if (v !== undefined) { r[k] = v; hasValues = true; } return r; }, {}); return hasValues ? temp : undefined; }, getNotNullish = value => { if (Array.isArray(value)) return getArray(value); if (value && typeof value === 'object') return getObject(value); return isNullish(value) ? undefined : value; }; var data = { emptyArray: [], arrayWithNullish: [null, {}, [], undefined], null: null, undefined: undefined, emptyString: '', zero: 0, false: false, true: true, emptyObject: {}, objectWithNullish: { null: null, emptyArray: [], undefined: undefined }, nestedObject: { nestedObject: { null: null, one: 1, emptyObject: {} }, nestedEmptyArray: [[], [[]]] } }; console.log(getNotNullish(data));
 .as-console-wrapper { max-height: 100% !important; top: 0; }

这是我想出的。 (感谢 Nina 提供样品;)

 const is_obj = x => x !== null && typeof x === 'object'; const is_arr = x => Array.isArray(x); const nullish = x => ( typeof x !== 'number' && typeof x !== 'boolean' && typeof x !== 'function' ) && ( x === undefined || x === null || x === '' || Object.values(x).reduce((res, x) => res && nullish(x), true) ); const clean = x => [x] .map(x => Object.entries(x)) .map(x => x.map(([k, v]) => is_arr(v) ? [ k , v.map(vv => is_obj(vv) ? clean(vv) : vv) ] : is_obj(v) ? [ k , clean(v) ] : [ k , v ])) .map(x => x.filter(([k, v]) => !nullish(v))) .map(x => Object.fromEntries(x)) .pop(); console.log(clean(data));
 <script> var data = { emptyArray: [], arrayWithNullish: [null, {}, [], undefined], null: null, undefined: undefined, emptyString: '', zero: 0, false: false, true: true, emptyObject: {}, objectWithNullish: { null: null, emptyArray: [], undefined: undefined }, nestedObject: { nestedObject: { null: null, one: 1, emptyObject: {} }, nestedEmptyArray: [[], [[]]] } }; </script>

这是我想出的(感谢 Nina 提供的测试数据):

 function stripNullsFromObject(obj) { function stripNullsFromArray(arr) { return arr.reduce((acc, cur) => { if (typeof cur === 'object' && !Array.isArray(cur) && cur !== null) { const nestedObj = stripNullsFromObject(cur); if (Object.entries(nestedObj).length > 0) { return acc.concat(nestedObj); } } if (Array.isArray(cur)) { const nestedArr = stripNullsFromArray(cur); if (nestedArr.length > 0) { return acc.concat(nestedArr); } } if (typeof cur !== 'object' && (!!cur || cur === 0 || cur === false)) { return acc.concat(cur); } return acc; }, []); } return Object.entries(obj).reduce((acc, [key, val]) => { if (typeof val === 'object' && !Array.isArray(val) && val !== null) { const nestedObj = stripNullsFromObject(val); if (Object.entries(nestedObj).length > 0) { return { ...acc, [key]: nestedObj, }; } } if (Array.isArray(val)) { const nestedArr = stripNullsFromArray(val); if (nestedArr.length > 0) { return { ...acc, [key]: nestedArr, }; } } if (typeof val !== 'object' && (!!val || val === 0 || val === false)) { return { ...acc, [key]: val, }; } return acc; }, {}); } const data = { emptyArray: [], arrayWithNullish: [null, {}, [], undefined], null: null, undefined: undefined, emptyString: '', zero: 0, false: false, true: true, emptyObject: {}, objectWithNullish: { null: null, emptyArray: [], undefined: undefined }, nestedObject: { nestedObject: { null: null, one: 1, emptyObject: {} }, nestedEmptyArray: [[], [[]]] } }; console.log(stripNullsFromObject(data))

我很好奇是否还有其他人有替代方法,或有关如何改进的建议。

我正在使用来自此处答案之一的数据样本。

var data = {
    emptyArray: [],
    arrayWithNullish: [null, {}, [], undefined],
    null: null,
    undefined: undefined,
    emptyString: '',
    zero: 0,
    false: false,
    true: true,
    emptyObject: {},
    objectWithNullish: { null: null, emptyArray: [], undefined: undefined },
    nestedObject: {
        nestedObject: {
            null: null,
            one: 1,
            emptyObject: {}
        },
        nestedEmptyArray: [[], [[]], 6]
    }
}; 

function clean(data){
    return (function inner(data, output){
        if (!isObject(data)){
        return data;
      }
      Object.keys(data).forEach(function(key){
      if(isObject(data[key]) && !Array.isArray(data[key])){
        var result = clean(data[key], output);
        updateVal(output, key, result);
      }else if(Array.isArray(data[key])){
        var new_arr = [];
        data[key].forEach(function(a_item){
           var a_result = clean(a_item, output);
           if (!isFalsy(a_result)){
                new_arr.push(a_item);
           }
        });
        updateVal(output, key, new_arr);
      }else{
          updateVal(output, key, data[key]);
       }
    });
    return output;
  })(data, {});
}

function updateVal(output,key, val){
    if(!isFalsy(val)){
    output[key] = val;
  }
}

function isObject(data){
    return typeof data === "object" && data !== null;
}

function isFalsy(val){
    return ['', undefined, null].indexOf(val) !== -1 ? 
        true:
        (()=>{
            return typeof(val) === "object" && Object.keys(val).length === 0 ? true: false;
        })();
}

console.log(clean(data));

暂无
暂无

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

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