[英]Recursively remove nullish values from a JavaScript object
我搜索了这个,但找不到满意的答案,所以我在这里发布我自己的答案。
基本上我想要一个函数:
null
、 undefined
、 []
、 {}
或''
属性0
和false
值您可以将三种类型的数据分开
并通过减少复杂数据类型和检查原始值来获得想要的子集。
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.