#javascript #loops #filter #callback #higher-order-functions
#javascript #циклы #Фильтр #обратный вызов #функции более высокого порядка
Вопрос:
Я ищу элегантный способ генерировать логические значения, которые в конечном итоге будут объединены с помощью оператора amp;amp; внутри моей функции обратного вызова в методе filter.
Я попытался выполнить цикл по условиям фильтрации, но я не могу найти способ объединить результат каждой итерации в следующий формат:
return Boolean amp;amp; Boolean amp;amp; Boolean amp;amp; Boolean amp;amp; Boolean
Потому что = amp;amp; Boolean не работает.
Вот что у меня есть и что работает:
//data I am filtering
this.preSearch = [
["The Lord of the Rings", "J. R. R. Tolkien", "English", "1955", "150 milionów"],
["Le Petit Prince (The Little Prince)", "Antoine de Saint-Exupéry", "French", "1943", "140 milionów"],
["Harry Potter and the Philosopher's Stone", "J. K. Rowling", "English", "1997", "120 milionów"],
["The Hobbit", "J. R. R. Tolkien", "English", "1937", "100 milionów"],
["And Then There Were None", "Agatha Christie", "English", "1939", "100 milionów"],
["Dream of the Red Chamber", "Cao Xueqin", "Chinese", "1791", "100 milionów"]
]
//filters, that are set dynamically but let's pretend they are equal to
var filters = ["", "", "english", "19", "1"]
var searchdata = this.preSearch.filter(row => {
return
row[0].toLowerCase().indexOf(filters[0].toLowerCase()) > -1
amp;amp; row[1].toLowerCase().indexOf(filters[1].toLowerCase()) > -1
amp;amp; row[2].toLowerCase().indexOf(filters[2].toLowerCase()) > -1
amp;amp; row[3].toLowerCase().indexOf(filters[3].toLowerCase()) > -1
amp;amp; row[4].toLowerCase().indexOf(filters[4].toLowerCase()) > -1
})
Мне нужно масштабируемое и более элегантное решение, чтобы мне не пришлось добавлять еще одну строку с amp; amp;, если я улучшу свой отфильтрованный массив.
Ответ №1:
Вы могли бы использовать Array#every
для массива filters.
Для более быстрой проверки вы могли бы заранее преобразовать значения фильтра в нижний регистр.
var preSearch = [["The Lord of the Rings", "J. R. R. Tolkien", "English", "1955", "150 milionów"], ["Le Petit Prince (The Little Prince)", "Antoine de Saint-Exupéry", "French", "1943", "140 milionów"], ["Harry Potter and the Philosopher's Stone", "J. K. Rowling", "English", "1997", "120 milionów"], ["The Hobbit", "J. R. R. Tolkien", "English", "1937", "100 milionów"], ["And Then There Were None", "Agatha Christie", "English", "1939", "100 milionów"], ["Dream of the Red Chamber", "Cao Xueqin", "Chinese", "1791", "100 milionów"]],
filters = ["", "", "english", "19", "1"].map(s => s.toLowerCase()),
result = preSearch
.filter(row => filters.every((v, i) => row[i].toLowerCase().includes(v)));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Ответ №2:
Вы можете сделать это, применив Array.every()
и String.includes()
вот так:
var searchdata = this.preSearch.filter(row => {
// this only returns true if our condition works for
// index = 0, 1, 2, 3, 4
return [0, 1, 2, 3, 4].every(index => {
const rowContent = row[index].toLowerCase();
const filterContent = filters[index].toLowerCase();
// String.includes() is nicer than String.indexOf() here because
// you don't need the ugly -1
return rowContent.includes(filterContent);
});
});