我有一个看起来像这样的对象:
var myObject = { a: { b: [{}], c: [{}, {d: 2}], e: 2, f: {} }, g:{}, h:[], i: [null, 2] }
我想要删除空值和空数组、空对象,使其看起来像这样:
我希望您能够从中删除空值和空对象(包括数组和对象),使其看起来如下:
{ a: {c: [ {d: 2} ], e: 2 }, i: [ 2 ] }
该函数应该移除空值,空对象和空数组。有没有一种优雅的方法来完成它?
我有一个看起来像这样的对象:
var myObject = { a: { b: [{}], c: [{}, {d: 2}], e: 2, f: {} }, g:{}, h:[], i: [null, 2] }
我希望您能够从中删除空值和空对象(包括数组和对象),使其看起来如下:
{ a: {c: [ {d: 2} ], e: 2 }, i: [ 2 ] }
这是一个递归清理对象的函数。它将深度遍历所有属性并删除null值、null数组和null对象:
cleanUpObject(jsonObject: object): object {
Object.keys(jsonObject).forEach(function (key, index) {
const currentObj = jsonObject[key]
if (_.isNull(currentObj)) {
delete jsonObject[key]
} else if (_.isObject(currentObj)) {
if (_.isArray(currentObj)) {
if (!currentObj.length) {
delete jsonObject[key]
} else {
const cleanupArrayObj = []
for (const obj of currentObj) {
if (!_.isNull(obj)) {
const cleanObj = this.cleanUpJson(obj)
if (!_.isEmpty(cleanObj)) {
cleanupArrayObj.push(cleanObj)
}
}
}
if (!cleanupArrayObj.length) {
delete jsonObject[key]
} else {
jsonObject[key] = cleanupArrayObj
}
}
} else {
if (_.isEmpty(Object.keys(jsonObject[key]))) {
delete jsonObject[key]
} else {
jsonObject[key] = this.cleanUpJson(currentObj)
if (_.isEmpty(Object.keys(jsonObject[key]))) {
delete jsonObject[key]
}
}
}
}
}, this)
return jsonObject
}
function clean(obj) {
// clean array
if (Array.isArray(obj)) {
for (let i=0; i<obj.length; i++) {
if (isNothing(obj[i])) obj.splice(i, 1); // remove value if falsy
else if (typeof obj[i] === 'object') clean(obj[i]); // recurse if it's a truthy object
}
// clean other object
} else {
for (let prop in obj) {
if (!obj.hasOwnProperty(prop)) continue;
if (isNothing(obj[prop])) delete obj[prop]; // remove value if falsy
else if (typeof obj[prop] === 'object') clean(obj[prop]); // recurse if it's a truthy object
}
}
}
// Recursively check for populated or nonnull content. If none found, return `true`. Recursive so [{}] will be treated as empty.
function isNothing(item) {
// null / undefined
if (item == null) return true;
// deep object falsiness
if (typeof item === 'object') {
if (Array.isArray(item)) {
// array -> check for populated/nonnull value
for (let i=0; i<item.length; i++) {
if (!isNothing(item[i])) return false;
}
return true;
}
// other object -> check for populated/nonnull value
for (let prop in item) {
if (!item.hasOwnProperty(prop)) continue;
if (!isNothing(item[prop])) return false;
}
return true;
}
return false;
}
var myObject = { a: { b: [{}], c: [{}, {d: 2}], e: 2, f: {} }, g:{}, h:[], i: [null, 2] };
console.log("Before: " + JSON.stringify(myObject));
clean(myObject);
console.log("After: " + JSON.stringify(myObject));
itemToBool
),该函数可以确定传递给它的通用值是否为真,或者在值为数组或对象时递归地确定其真实性。然后,在传递原始对象的函数中(或者在递归传递对象或数组的函数中),每当需要验证值时,都可以调用itemToBool
函数。map
和itemToBool
,然后通过布尔值filter
。对于对象,将对象的entries
缩减为另一个对象:将对象的每个值通过itemToBool
递归转换(如果值是数组或对象,则进行转换),如果转换后的值具有任何键(或为真实的基元),则将其分配给累加器。无需依赖库:
var myObject = {
a: {
b: [{}],
c: [{}, {
d: 2
}],
e: 2,
f: {}
},
g: {},
h: [],
i: [null, 2]
};
// Returns a falsey value if the item is falsey,
// or if the deep cleaned array or object is empty:
const itemToBool = item => {
if (typeof item !== 'object' || item === null) return item;
const cleanedItem = clean(item);
return Object.keys(cleanedItem).length !== 0 && cleanedItem;
};
const clean = 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) a[key] = newVal;
return a;
}, {});
return Object.keys(newObj).length > 0 && newObj;
};
console.log(clean(myObject));
var myObject={a:{b:[{}],c:[{},{d:2}],e:2,f:{}},g:{},h:[],i:[null,2]}
// Returns the object / array if it has at least one key, else returns false:
const validObj = obj => Object.keys(obj).length && obj;
const itemToBool = item => (
typeof item !== 'object' || item === null
? item
: validObj(clean(item))
);
const clean = obj => validObj(
Array.isArray(obj)
? obj.map(itemToBool).filter(Boolean)
: Object.entries(obj).reduce((a, [key, val]) => {
const newVal = itemToBool(val);
if (newVal) a[key] = newVal;
return a;
}, {})
);
console.log(clean(myObject));
a.c
是一个数组,为什么非空数组没有被保留,即{ a: { c: [{ d: 2 }], e: 2}, i: [2] }
?为什么[null, 2]
的i
数组会消失,然后出现在g
的属性中?为什么输出中有两个嵌套的c
属性,而输入中只有一个c
属性? - CertainPerformance{ a: { c: [{ d: 2 }], e: 2}, i: [2] }
,这与问题描述中所期望的一致,因此我假设问题中发布的期望输出只是打字错误? - CertainPerformance