根据传递的输入过滤对象数组:Javascript

Posted

技术标签:

【中文标题】根据传递的输入过滤对象数组:Javascript【英文标题】:Filter array of objects based on the input passed: Javascript 【发布时间】:2020-11-05 01:33:26 【问题描述】:

我有一个具有以下结构的对象数组

arr = [  name: "abc" , items: ["itemA","itemB","itemC"], days :138 ,
         name: "def" , items: ["itemA1","itemB2","itemC1"], days :157 ,
         name: "hfg" , items: ["itemAN","itemB7","itemC7"], days :189 ]

此数组需要根据传递的搜索输入进行过滤。我能够为 name 实现相同的效果,其中天数没有被过滤。

也有人可以帮助如何搜索 items 数组,以便它根据传递的输入过滤行

这是我尝试过的

  handleSearch = (arr, searchInput) => 
    let filteredData= arr.filter(value => 
      return (
        value.name.toLowerCase().includes(searchInput.toLowerCase()) ||
        value.days.toString().includes(searchInput.toString())
      );
    );
    console.log(filteredData);
    //this.setState( list: filteredData );
  


【问题讨论】:

我猜你是想写value.days.toString().includes(searchInput.toLowerCase())? 但 days 是一个数字,所以尝试在两者上运行 toString 过滤内部数组遵循与您已经在做的类似的逻辑,您应该过滤value.items 这不是重点,问题是您正在测试days 是否包含days,这是无稽之谈。无论如何,只需使用[item.name, item.items.join(','), item.days].join(',') 得到一个逗号分隔的字符串,其中包含所有字符串和日期,然后在上面使用includes() 是的,但是:1) 谁将在搜索词中添加逗号 2) OP 可以先从搜索词中删除逗号 3) 或使用晦涩的字符 【参考方案1】:

您可以使用Array#some,然后执行您已经完成的相同类型的匹配:

some() 方法测试数组中的至少一个元素是否通过了提供的函数实现的测试。它返回一个布尔值。

  handleSearch = (arr, searchInput) => 
    const filteredData = arr.filter(value => 
      const searchStr = searchInput.toLowerCase();
      const nameMatches = value.name.toLowerCase().includes(searchStr);
      const daysMatches = value.days.toString().includes(searchStr);
      const oneItemMatches = value.items.some(item => item.toLowerCase().includes(searchStr));

      return nameMatches || daysMatches || oneItemMatches;
    );
    console.log(filteredData);
    //this.setState( list: filteredData );
  

【讨论】:

find方法呢? find 方法适用于您要检索数组值的情况。如果您将find 方法与函数item => item.toLowerCase().includes(searchStr) 一起使用,它将返回数组中与该谓词匹配的第一个元素【参考方案2】:

由于您的搜索值可以应用于数据数组中的所有字段,因此您可以将这些值组合到一个数组中(逐行)并在一个位置执行搜索。

为此,我在下面提供了一个 sn-p,它将过滤原始数组,在转换后检查每个对象的值。这些涉及使用Object.values() 来获取数组中对象的值,由于该数组是嵌套的,我们可以使用Array.flat() 将其扁平化为字符串和数字,最后调用Array.some() 来检查是否有的值部分包括搜索值(在它们都是小写-d 之后)。

const arr = [
     name: "abc" , items: ["itemA","itemB","itemC"], days: 138 ,
     name: "def" , items: ["itemA1","itemB2","itemC1"], days: 157 ,
     name: "hfg" , items: ["itemAN","itemB7","itemC7"], days: 189 
];

const handleSearch = (arr, searchInput) => (
    arr.filter((obj) => (
        Object.values(obj)
              .flat()
              .some((v) => (
                  `$v`.toLowerCase().includes(`$searchInput`.toLowerCase())
              ))
    ))
);

console.log('"A1" =>', JSON.stringify(handleSearch(arr, 'A1')));
console.log('189 =>', JSON.stringify(handleSearch(arr, 189)));
console.log('"nope" =>', JSON.stringify(handleSearch(arr, 'nope')));

注意: 这种方法有一个明显的缺陷,它会将数字作为字符串进行搜索,这意味着提供89 作为搜索值仍然会返回第二个元素.

【讨论】:

find方法呢? Array.filter() 不同,Array.find() 只会返回第一个找到的元素(如果有)。如果这就是你想要的,那么你可以替换那个调用。

以上是关于根据传递的输入过滤对象数组:Javascript的主要内容,如果未能解决你的问题,请参考以下文章

根据 GPS 位置之间的距离过滤对象数组(javascript)

如何根据 Javascript 中的用户输入过滤数组?

根据用户输入 javascript 返回一个过滤后的数组

JavaScript 根据属性值过滤对象数组

数组 - Javascript - 使用输入搜索过滤对象数组

javascript 根据选择条件过滤数组对象。