如何解决如何理解JavaScript中的这段代码片段
这是一个重新编写,力求清晰,并简化了逻辑以消除干扰:
const recursivelyFilter = (arr, key, searchString) => {
return arr.filter(function iter(obj) {
if (obj[key].includes(searchString)) {
return true;
}
if (obj.children) {
obj.children = obj.children.filter(child => iter(child));
return obj.children.length > 0;
}
return false;
});
};
Array#filter
是此代码的内容。filter
接受一个回调,该回调应返回一个布尔值以确定元素是否将包含在结果数组中。它不能就地工作。
所述碱的情况下(对于递归终止条件)为:
- 如果当前的对象(节点在树)有一个
key
键匹配searchTerm
,返回true。 - 如果当前节点不匹配
searchTerm
且没有子节点,则返回false。在原始代码中,返回undefined
默认值为false。
递归的情况是:
- 如果当前节点有子节点,则使用
iter
函数的布尔结果来递归过滤它们。如果当前节点的至少一个后代通过了过滤条件,则将当前节点包括在其父节点的children
数组中,否则将其删除。该代码将新的子数组的长度作为布尔值来实现。
return (o.children =
o.children.filter(iter)).length;
首先执行对的分配o.children
,这是必要的,因为它会o.children.filter
返回数组的新副本。分配完成后,表达式将解析为新表达式,o.children
并length
返回其属性。然后根据上述递归情况规则,将该长度视为真/假。总计:
obj.children = obj.children.filter(child => iter(child));
return obj.children.length > 0;
如果我们返回数组本身,则所有内容都将被视为true,因为空数组的结果[]
为true。[].length
另一方面,求值为假,这是期望的结果。
至于o.children.filter(iter)
,Array#filter
则将回调作为第一个参数,该参数可以是函数变量,例如iter
。另一种选择是直接在参数列表中创建一个匿名函数。这通常是这样做的。上面的版本添加了一个箭头包装器,但是由于lone参数只是通过包装器传递,因此这显然是不必要的额外间接层。我们也可以在function
这里使用关键字。无论如何,目标是相同的,那就是我们将一个函数传递给filter
每个元素。
顺便说一句,该函数假定key
已在嵌套对象的所有节点上设置array
且obj[key].includes
已定义。显然,作者在心中有一个非常具体的数据结构和目的,对过早的概括不感兴趣。
这是说明其操作的测试代码。玩弄它应该有助于您的理解。
const recursivelyFilter = (arr, key, searchString) => {
return arr.filter(function iter(obj) {
if (obj[key].includes(searchString)) {
return true;
}
if (obj.children) {
obj.children = obj.children.filter(child => iter(child));
return obj.children.length > 0;
}
return false;
});
};
const arr = [
{
foo: "bar",
children: [
{
foo: "baz",
children: [
{foo: "quux"},
{foo: "quuz"},
]
}
]
},
{
foo: "corge",
children: [
{foo: "quux"}
]
},
{
foo: "grault",
children: [{foo: "bar"}]
}
];
console.log(recursivelyFilter(arr, "foo", "quux"));
解决方法
我在Internet上的js中发现了该函数的实现,该函数递归地过滤了一个对象数组,每个对象都可能具有属性“
children”(即对象数组),并且该对象也可能具有子对象,依此类推。该功能正常工作,但我一点也不了解。
这是我的功能:
getFilteredArray (array,key,searchString) {
const res = array.filter(function iter(o) {
if (o[key].toLowerCase().includes(searchString.toLowerCase())) {
return true;
}
if(o.children){
return (o.children = o.children.filter(iter)).length;
}
});
this.setState({
filteredArray: res
});
}
我不明白这段代码:
if(o.children){
return (o.children = o.children.filter(iter)).length;
}
我们可以简化这个表达(o.children = o.children.filter(iter)).length;
吗?
为什么我们返回数组的长度而不是数组本身?
函数“ iter”接受一个作为对象的参数。为什么我们只写o.children.filter(iter)而没有任何参数传递给“
iter”呢?根据递归教程,如果函数需要它们,则总是传递参数。但是在这里我们没有通过,这很奇怪。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。