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

Filter array of objects based on the input passed: Javascript

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

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 });
  }


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

为此,我在下面提供了一个片段,它将过滤原始数组,检查转换后每个对象的值。这些涉及使用 Object.values() to get the values of the object in an array, since this array is nested, we can make use of Array.flat() to flatten it into just the strings and numbers, finally call 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因为搜索值仍然是 return 第二个元素。

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

The some() method tests whether at least one element in the array passes the test implemented by the provided function. It returns a Boolean value.

  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 });
  }