javascript - 如何理解javascript React中的这段代码

标签 javascript arrays reactjs recursion search

我在网上找到了该函数在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”?根据递归教程,如果函数需要参数,则总是会传递参数。但这里我们没有通过,这很奇怪。

最佳答案

这是一个重写,力求清晰并稍微简化逻辑以消除干扰:

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接受一个回调,该回调应返回一个 bool 值以确定某个元素是否包含在结果数组中。它不起作用in-place .

base cases (递归的终止条件)是:

  • 如果当前对象( node 中的 tree )具有 key key 匹配searchTerm ,返回true。
  • 如果当前节点不匹配searchTerm并且没有 child ,返回 false。在原始代码中,返回 undefined默认为 false。

递归情况是:

  • 如果当前节点有子节点,则使用iter的 bool 结果递归过滤它们。功能。如果当前节点的至少一个后代通过过滤条件,则将当前节点包含在其父节点的 children 中数组,否则将其删除。该代码将新子数组的长度视为 bool 值来实现此目的。

return (o.children = o.children.filter(iter)).length;首先执行对 o.children 的赋值,必要的,因为 o.children.filter返回数组的新副本。赋值完成后,表达式解析为新的 o.children及其 length属性(property)被归还。然后根据上述递归案例规则将长度视为真/假。这相当于:

obj.children = obj.children.filter(child => iter(child));
return obj.children.length > 0;

如果我们返回数组本身,则所有内容都将被视为 true,因为空数组 [] ,评估结果为真。 [].length另一方面,计算结果为 false,这是期望的结果。

至于o.children.filter(iter) , Array#filter接受回调作为其第一个参数,该参数可以是函数变量,例如 iter 。另一种选择是直接在参数列表中创建匿名函数;通常就是这样完成的。上面的版本添加了一个箭头包装器,但这显然是不必要的额外间接层,因为单独的参数只是通过包装器传递。我们还可以使用function此处为关键字;不管怎样,目标都是一样的,那就是我们将一个函数传递给 filter调用每个元素。

顺便说一句,该函数假设 keyarray 中嵌套对象的所有节点上设置那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"));

关于javascript - 如何理解javascript React中的这段代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57652942/

相关文章:

javascript - 使用 backbone.js 和其他服务器脚本语言将数据存储在 mysql 中

javascript - 如果匹配则获取第一个值

java - 如何将元素复制到没有大写字符的第二个数组?

javascript - onClick onClick on "a"如果它在 react 中有一些子元素,则标签无法正常工作

javascript - Chrome 扩展 - 与外部程序通信

javascript - 扫描文件夹内的文本文件名称 HTML5/Javascript

c - 将c中的.csv文件读入多个变量

javascript - 更新状态时无法在现有状态转换期间更新?

javascript - 自定义 tradingview charting_library 标题

javascript - 在 React 中的功能组件上设置 defaultProps