让我们将假值定义为以下(我自己的定义)JS值之一:
""
(空字符串)0
(零,或它的任何"变化",如0.0、-0等)false
(boolean)[]
(空数组){}
(空对象)
我想递归地查找对象或数组是否只包含空值。下面是一些例子:
{"x": 0}
(是,对于对象只考虑叶值){"x": {"y": [0,0,[]]}}
(yes)[0,0,[],{}]
(yes)[[[]], [], {}]
(yes)[1]
(no)
怎么做呢?我更喜欢函数式风格,因为那些答案似乎总是最有创意,读起来也很有趣!
到目前为止,我有这样的内容:
let arr = [];
function isEmpty(val) {
if (typeof(value) === 'object') {
for (subval of val) {
arr.push(isEmpty(subval));
}
} else {
arr.push(["", 0, false, [], {}].indexOf(val) !== -1);
}
}
// now see if the arr is something like [false, false, ...]
你实现的问题是[] !== []
和{} !== {}
,这是indexOf()
使用的比较,所以你永远不会得到空数组和对象的任何匹配。
相反,对于对象和数组,您可以使用array .prototype.every()
递归地检查它们的可迭代值。
const isEmpty = (val) => {
if (!val) {
// any implicitly falsy value; false, 0, "", null and undefined
return true;
}
if (typeof val === "object") {
// recursively check every value, returns true for an empty collection
return Object.values(val).every(isEmpty);
}
// otherwise, it is not empty
return false;
}
const test = [
{"x": 0},
{"x": {"y": [0,0,[]]}},
[0,0,[],{}],
[[[]], [], {}],
[1],
];
test.forEach((val) => {
console.log(isEmpty(val) ? 'empty' : 'not empty', JSON.stringify(val));
});
注意:这只适用于对象和数组字面量。迭代器很难可靠地从。
中提取值。