Поиск по нескольким свойствам в объекте, используя только один вход, иначе глобальный поиск - PullRequest
0 голосов
/ 14 мая 2019

Я пытаюсь создать универсальный / глобальный поиск объекта в реагирующих, используя только один текстовый ввод.

Я пробовал разные подходы, включая преобразование строки в массив и последующее использование ее для фильтрации моего объекта. Мне удалось выполнить поиск по всем свойствам, но только по одному за раз.

const data = [
  {
    name:"Italy",
    title:"Best place for Pizza"
  },
  {
    name:"USA",
    title:"It is a federal state"
  }
]
export class MyApp extends React.Component{
  constructor(props){
    super(props);
    this.state = {
      filteredData:[],
      filter:''
    }
    this.handleSearch.bind(this);
  }
  componentDidMount(){
    this.setState({
      filteredData:data
    })
  }

  handleSearch = (e) =>{
    const filter = e.target.value;

    this.setState({
      filter
    })
  }
  render(){
    var filteredData = data;
    var searchValue = this.state.filter;
    filteredData = filteredData.filter(country => {
      return['name', 'title'].some(key =>{
        return country[key].toString().toLowerCase().includes(searchValue)
      })
    })

    return (
      <div>
        <input type="search" onChange={(e) => this.handleSearch(e)}/>
        {
          filteredData.map(result =>{
              return <p>{result.name} | {result.title}</p>
          })
        }
      </div>
    );
  }

То, что я хочу, - это возможность комбинировать свойства. Например: я хочу набрать «Италия лучшее место для ...» и все равно получить результат. Я не хочу, чтобы вас ограничивали вводом «Лучшее место для пиццы» или «Италия» для получения заявки.

Ответы [ 2 ]

1 голос
/ 14 мая 2019

Вы можете сделать поиск похожим на это:

const data = [ { name:"Italy", title:"Best place for Pizza" }, { name:"USA", title:"It is a federal state" } ]

let search = (arr, str) => {
 return arr.filter(x => Object.values(x)
  .join(' ')
  .toLowerCase()
  .includes(str.toLowerCase()))
}

console.log(search(data, 'Italy best'))
console.log(search(data, 'USA it is'))

Идея состоит в том, чтобы использовать Array.filter и внутри получить значения объекта (используя Object.values ​​) (здесь мы предполагаем, что все они являются строками) и объединить их ( через Array.join ) в одну строку. Затем используйте Array.includes для поиска внутри него.

1 голос
/ 14 мая 2019

Я не уверен, является ли это наилучшей практикой или нет, но когда я столкнулся с подобной проблемой, я просто продолжал связывать свои .filter() функции друг с другом, при этом каждый фильтр просматривал свое свойство.

filteredData = filteredData.filter(country => {
    return country['name'].toString().toLowerCase().includes(searchValue)
      }).filter(country => {
    return country['title'].toString().toLowerCase().includes(searchValue)
    })

Работает, но выглядит не так красиво.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...