#javascript #lodash
#javascript #Lodash
Вопрос:
У меня есть два объекта / массива, которые мне нужно сравнить для системы фильтрации, и вот грубый набор данных:
var books = [{
'title': 'book a',
'relatedIds': [1, 2],
'authorId': 1,
},{
'title': 'book b',
'relatedIds': [1, 2, 3, 4],
'authorId': 2,
},{
'title': 'book a',
'relatedIds': [1],
'authorId': 3,
}];
var filters = {
'relatedIds' : [1, 2, 3],
'author': [1, 2]
};
Что я ожидаю увидеть для вышеупомянутых фильтров, которые book a
(имеют связанные идентификаторы 1 и 2 и идентификатор автора 1 из filter) и book b
(имеют связанные идентификаторы 1, 2 и 3 и идентификатор автора 2 из filter).
Я бы не ожидал увидеть, book c
поскольку, несмотря на то, что у него правильный связанный идентификатор, его автором является 3, которого нет в фильтре.
Я пытался использовать метод фильтрации Lodash:
_.filter(books, (book) => {
....
Но я не вижу, как я могу выполнять сравнения на основе массивов из фильтра либо с массивом, либо с int / string в книгах.
Комментарии:
1. На самом деле вы не показали, что вы пробовали при использовании фильтра Lodash.
Ответ №1:
Вы можете использовать filter, some и включает:
filter
используется для получения только желаемого результата из исходных данныхsome
используется для проверки того, доступен какой-либоrelatedId
элемент вfilters
‘srelativeId
или нетincludes
используется для проверки, доступно ли данное значение в массиве.
var books = [{'title': 'book a','relatedIds': [1, 2],'authorId': 1,},{'title': 'book b','relatedIds': [1, 2, 3, 4],'authorId': 2,},{'title': 'book a','relatedIds': [1],'authorId': 3,}];
var filters = {
'relatedIds' : [1, 2, 3],
'author': [1, 2]
};
let op = books.filter(({relatedIds,authorId})=>(
relatedIds.some(id=> filters.relatedIds.includes(id))
amp;amp; filters.author.includes(authorId)
))
console.log(op)
Комментарии:
1. Это отличный ответ, вы не могли бы объяснить эту строку
relatedIds.some(id=> filters.relatedIds.includes(id))
и что происходит?2. @panthro добавьте объяснение, вы можете проверить
3. Спасибо, я все еще не уверен, почему вы используете
some
and thenincludes
? Конечно,some
было бы достаточно проверить, доступен ли какой-либоrelatedId
элемент в фильтрахrelativeId
или нет?4. @panthro поскольку
relatedId
в вашемdata
иfilter
также есть массив, поэтому вам нужно сравнивать каждое значениеdata's relatedId
сfilters relatedId
, если вы не найдете совпадения5. Неважно, теперь я понимаю,
some
элемент вrelatedIds
должен бытьincludes
вfilterIds
, и только по крайней мере один из элементов должен пройти этот тест — правильно?
Ответ №2:
Используйте _.intesection()
для поиска похожих элементов в relatedIds
, проверяя длину результата (0, если похожих элементов нет). Используйте _.includes()
, чтобы проверить, находится ли authorId
в author
массиве фильтров:
const books = [{"title":"book a","relatedIds":[1,2],"authorId":1},{"title":"book b","relatedIds":[1,2,3,4],"authorId":2},{"title":"book a","relatedIds":[1],"authorId":3}];
const filters = {"relatedIds":[1,2,3],"author":[1,2]};
const result = _.filter(books, o =>
_.intersection(o.relatedIds, filters.relatedIds).length amp;amp;
_.includes(filters.author, o.authorId)
);
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>