Как отфильтровать массив объектов в React

#javascript #reactjs

Вопрос:

 movies = [
   {
    id:1,
    title: "movie1",
    genre:["action","sci-fi"],
    country:["usa","uk"]
   },
   {
    id:2,
    title: "movie2",
    genre:["action","comedy"],
    country:["usa","ireland"]
   },
   {
    id:3,
    title: "movie3",
    genre:["comedy","romance"],
    country:["ireland","uk]
   },
]
 

Я хочу отфильтровать фильмы по жанрам и странам. Я могу сделать это очень странным способом. Но мне интересно, каков кратчайший путь фильтрации. Есть ли какой-либо вариант, который я могу отфильтровать, если реквизит или реквизит существуют, если не оставить оригинал?

 const Component = ({ genre, country }) => {
  const [movies,setMovies]=useState([]);
  const [filteredMovies,setFilteredMovies]=useState([])

    useEffect(()=>{
    //fetch from api and set movies
  },[])
  
  useEffect(()=>{
    setFilteredMovies(
      movies.filter((item) =>
        {
           if(genre || country){
              if(!country){
                 return item.genre.includes(genre)
              }elseif(!genre){
                 return item.country.includes(country)
              }else{
                 return item.genre.includes(genre) amp;amp; item.country.includes(country)
              }
           }else return item
        }
      )
    );
  },[movies,genre,country])

  return (
    <div>
      {filteredMovies.map((item) => (
        <Movie item={item} key={item.id} />
      ))}
    </div>
  );
}
 

Ответ №1:

Я рекомендую использовать lodash , это сделать filter просто

    _.filter(movies , { genre: ["action"] });
 

вы можете ознакомиться с документацией: https://lodash.com/docs/4.17.15#filter

и, пожалуйста, попробуйте мой эксперимент:

Редактировать lodash

Ответ №2:

Измените порядок данных таким образом, чтобы вы могли ввести одно значение или объект, которые можно использовать для фильтрации данных в фильмах. Например, если бы вы расположили свой фильтр следующим образом: (что вы уже сделали, если бы не разрушали)

 const filters = {
  genre: 'action',
  country: 'ireland'
};
 

Затем вы можете просмотреть каждый фильм и использовать свойства фильтров, чтобы получить доступ только к свойствам фильма, который вы хотели бы проверить, например, к псевдокоду ниже.

 movie[property].includes(value)
 

При этом вы можете опустить или добавить любой фильтр, который вам нравится.

Имейте в виду, что в текущем состоянии приведенный ниже фрагмент предполагает, что он должен работать только с массивом.

 const filters = {
  genre: 'action',
  country: 'ireland'
};
  
const movies = [
  {
    id: 1,
    title: "movie1",
    genre: ["action", "sci-fi"],
    country: ["usa", "uk"]
  },
  {
    id: 2,
    title: "movie2",
    genre: ["action", "comedy"],
    country: ["usa", "ireland"]
  },
  {
    id: 3,
    title: "movie3",
    genre: ["comedy", "romance"],
    country: ["ireland", "uk"],
  },
];

const filterMovies = (movies, filters) =>
  movies.filter(movie => 
    Object.entries(filters).every(([key, value]) => 
      movie[key].includes(value)
    )
  )

const result = filterMovies(movies, filters);
console.log(result); 

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

1. Это хорошая идея-создать все фильтры в объекте. Спасибо.

Ответ №3:

Чтобы сделать это немного более ES6-y

 movies.filter((item) =>{

    const [movieGenre, movieCountry] = [item.genre.includes(genre),item.country.includes(country)]

  if(movieGenre amp;amp; movieCountry) true
  if(!movieGenre amp;amp; !movieCountr) false

 return movieGenre ? movieGenre : movieCountry

      })