#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
и, пожалуйста, попробуйте мой эксперимент:
Ответ №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
})