как фильтровать строки в массиве? - PullRequest
0 голосов
/ 25 октября 2019

Я пытался найти функцию. Эта функция проверяет вложенный массив с несколькими строками, а затем возвращает, если в массиве есть слово для поиска.

Структура данных массива

[
  {
   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 ]

2 голосов
/ 25 октября 2019

Вам нужно перебрать массив searchWords, чтобы найти, соответствует ли он поисковому слову. Этот будет работать
const filterItems = list.filter( (item) => item.searchWords.filter((myWord) => myWord.indexOf(searchWord)>-1) );

1 голос
/ 25 октября 2019

Вы можете попробовать с find() и includes() для свойства name объекта и, наконец, 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);
});
<input id="searchWord"/>
0 голосов
/ 25 октября 2019

Проблема с кодом заключается в том, что он пытается найти, содержит ли массив слово, когда вы используете indexOf. Например: при поиске «а» код проверяет, есть ли в массиве слово «а», а не слово, содержащее букву «а».

Вам необходимо изменить часть 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">
  </>
0 голосов
/ 25 октября 2019

Это потому, что indexOf работает с array и strings.

скажем, синтаксис indexOf равен

operatedItem.indexOf(searchedItem);

Здесь, в вашем случае

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

name это строка ,

и 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
0 голосов
/ 25 октября 2019

Вы можете использовать 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...