如何过滤数组中的字符串?

时间:2019-10-25 05:10:21

标签: javascript reactjs redux

我正在尝试搜索功能。此函数检查具有多个字符串的嵌套数组,然后返回该数组是否包含搜索词。

数组的数据结构

[
  {
   name:'aa',
   searchWords:['aa','ab','bc'] <- I want to use this array for search
  },
  {
   name:'bb',
   searchWords:['bb','bc','de'] <- I want to use this array for search
  },
...
]

我尝试使用indexOf函数。
但是,我无法在下面的代码中显示任何组件。
但是我在代码中将目标值从 item.searchWords 更改为 item.name 。它起作用了。

HTML
<div className="itemWrapper">
     {filterItems.map((item, idx) => (
            <Item key={idx} {...item} id={idx} list={list} />
      ))}
</div>    


Js
const filterItems = list.filter(
      (item) => item.searchWords.indexOf(searchWord) !== -1,
    );

我想要的结果是搜索结果实时更新。
例如,使用与上面相同的数据结构,当用户搜索“ a”时,searchWords“ aa”和“ ab”返回true以显示项目

非常感谢您的帮助。

5 个答案:

答案 0 :(得分:1)

您需要遍历searchWords数组以查找它是否与搜索词匹配。 这个会工作的
const filterItems = list.filter( (item) => item.searchWords.filter((myWord) => myWord.indexOf(searchWord)>-1) );

答案 1 :(得分:1)

您可以在对象的名称属性上使用<ejs-multiselect id='multiselectelement' [dataSource]='sportsData' [fields]='fields' [(value)]="value" [placeholder]='placeholder' (select)="select($event)" (destroyed)="onDestroyed($event)" (change)="OnChange($event)"></ejs-multiselect> find(),最后使用includes()

演示:

filter()
var list = [
  {
   name:'aa',
   searchWords:['aa','ab','bc'] 
  },
  {
   name:'bb',
   searchWords:['bb','bc','de']
  }
]

document.getElementById('searchWord').addEventListener('input', function(){
  console.clear();
  var filterItems = list.find(item => item.name.includes(this.value));
  filterItems = filterItems ? filterItems.searchWords : [];
  filterItems = filterItems.filter(i => i.includes(this.value));
  console.log(filterItems);
});

答案 2 :(得分:0)

您可以使用array#reduce并通过检查搜索词来使用searchWords过滤array#filter数组。

const dataSource = [{
      name: 'aa',
      searchWords: ['aa', 'ab', 'bc']
    },
    {
      name: 'bb',
      searchWords: ['bb', 'bc', 'de']
    }
  ],
  searchWord = 'a',
  result = dataSource.reduce((res, {name, searchWords}) => {
    let matched = searchWords.filter(word => word.includes(searchWord));
    if(matched.length) {
      res.push({name, searchWords: matched});
    }
    return res;
  },[])

console.log(result);

答案 3 :(得分:0)

这是因为 indexOf 如何与arraystrings一起工作。

假设indexOf的语法

operatedItem.indexOf(searchedItem);

在这里,就您而言

{
   name:'bb',
   searchWords:['bb','bc','de']
}

名称是字符串

searchWords是一个数组

执行时:

name.indexOf(“ b”); // 0

name.indexOf(“ bb”); // 0

name.indexOf(“ a”); //-1

它将检查searchedItem中是否存在operatedItem

let str = "aa ab a bb";

console.log(str.indexOf("a")); //0

console.log(str.indexOf("aa")); //0

console.log(str.indexOf("ab")); //3

console.log(str.indexOf("b")); //4

console.log(str.indexOf("c")); //-1

console.log(str.indexOf("aaa")); //-1

并且 indexOf与数组一起使用时,

它检查searchedItem数组中是否存在operatedItem它不会用于子字符串搜索。

let arr = ["aa", "ab", "a", "bb"];

console.log(arr.indexOf("a")); //2

console.log(arr.indexOf("aa")); //0

console.log(arr.indexOf("ab")); //1

console.log(arr.indexOf("b")); //-1

console.log(arr.indexOf("c")); //-1

console.log(arr.indexOf("aaa")); //-1

答案 4 :(得分:0)

代码的问题在于,当您使用indexOf时,它试图查找数组是否包含单词。例如:当您搜索“ a”时,代码将检查数组中是否有单词“ a”,而不是包含字母“ a”的任何单词。

您需要将JS部分更改为:

Js

const list = [{
    name: 'aa',
    searchWords: ['aa', 'ab', 'bc']
  },
  {
    name: 'bb',
    searchWords: ['bb', 'bc', 'de']
  }
];

let searchWord = "a";

const filterItems = list.filter(
  (item) => item.searchWords.filter(word => word.includes(searchWord)).length > 0
);

document.getElementById('result').innerHTML = JSON.stringify(filterItems);
<p id="result">
  </>