Фильтр путем сравнения вложенного свойства с термином поиска

#javascript #arrays #angular #typescript

#javascript #массивы #угловой #typescript

Вопрос:

В моем typescript я хочу фильтровать, сравнивая вложенное свойство с поисковым термином. Например, у меня есть массив объектов, например:

 var array = [
      {
        game: 'Cricket',
        team: ['Sally','Bob','John'],
      },
      {
        game: 'Basketball',
        team: ['Linda', 'George'],
      }
]
  

Если я ищу ‘John’, то результат должен быть:

 [
  {
    game: 'Cricket',
    team: ['John']
   }
]
  

Как я могу этого добиться?

Комментарии:

1. Какие другие критерии поиска вы хотите поддерживать? Можете ли вы записать подпись функции, которую вы хотите реализовать? serchByGame, searchByItem? Всегда ли этот массив имеет одинаковую структуру?

2. поиск только по элементу, а массив всегда имеет одинаковую структуру

3. Отфильтрованный team должен быть ['Sally','Bob','John'] или просто ['John'] ?

4. Изначально команды имеют длину массива около 10 , из этого я просто хочу показать [‘John’] (т. Е. Строку, которую я ввел в текстовое поле — например, John)

Ответ №1:

Исходя из ваших ожиданий, должно сработать следующее:

Использование reduce

 type Game = {
  game: string
  team: string[]
}

const games = [
  {
    game: 'Cricket',
    team: ['Sally', 'Bob', 'John']
  },
  {
    game: 'Basketball',
    team: ['Linda', 'George']
  }
]

const filterByTeamMember = (games: Game[], member: string): Game[] =>
  games.reduce<Game[]>(
    (p, c) => (c.team.includes(member) ? [...p, { ...c, team: [member] }] : p),
    []
  )

console.log(filterByTeamMember(games, 'Linda'))
// OUTPUT
// [ { game: 'Basketball', team: [ 'Linda' ] } ]

  

Использование flatMap

 const filterByTeamMember = (games: Game[], member: string): Game[] =>
  games.flatMap((game) => (game.team.includes(member) ? [{ ...game, team: [member] }] : []))

  

Ответ №2:

Итак, насколько я понимаю. вы хотите выполнить поиск по элементу, в котором например «john» является членом команды? вот быстрое решение, которое вы можете изменить в соответствии с вашими потребностями

 const a = [{
    game: 'Cricket',
    team: ['Sally', 'Bob', 'John']
  },
  {
    game: 'Basketball',
    team: ['Linda', 'George']
  }
]
const target = "John";
// this filters the array by checking if the current element fits the criteria and returns the element
const res = [];
a.map(el =>  el.team.includes(target) 
  ? res.push({...el, team: [target]}) 
  : false
);

console.log(res);  

Редактировать: вот исправление. вместо этого вам нужно использовать map, если вы хотите сделать это в одну строку, в противном случае вам нужно перебирать результирующий массив и изменять его.

Комментарии:

1. Спасибо, но результат должен возвращать только Джона, а не всех трех Салли, Боба, Джона

2. Вы можете редактировать структуру результирующего массива, я только показал, как фильтровать

3. ОК. Я уже использовал фильтр, но не получил ожидаемого результата — он возвращает весь массив — вот мой вопрос