Я работал над несколькими проектами с тех пор, как впервые начал учиться кодировать, и мне еще многое нужно для опыта, особенно для работы с массивами. В моем текущем проекте есть панель поиска на каждой странице, поэтому я знал, что должен убедиться, что то, что вводится в строку поиска, пройдет через массив в моей базе данных и найдет все совпадающие объекты.
Я узнал, что лучший путь здесь — создать пустой локальный массив, получить всю коллекцию базы данных и заменить ею пустой массив. Затем я мог бы отфильтровать объекты, чтобы остались только те, которые включают поисковый запрос в строке поиска. С этой конкретной базой данных у меня не было возможности использовать параметры запроса, чтобы сделать это за меня.
const searchButton = $('#searchbutton') const searchBar = $('#search') searchButton.click(function (event) { // Do not allow search on search button click if the search bar is empty. if (searchBar.value === "") { return; } let searchTerm = searchBar.val() let searchResults = placesArray.filter(function (name) { return name.includes(searchTerm); })
Вот с чего я начал, и с моим ограниченным опытом работы с методами массива мне потребовалась минута, чтобы привести array.filter в то место, где, как я думал, он мог бы делать то, что мне нужно. Но с этим была проблема. Аргумент, который я выбрал для функции обратного вызова, представлял часть информации, которая была на один уровень глубже фактического местоположения аргумента в такой функции обратного вызова.
Массив выглядит примерно так. Я пытался получить доступ к имени внутри объекта (Hotdog hut), даже не зная, как аргумент поймет доступ к нему.
let placesArray = [ { name: Hotdog hut, phone number: 1234567890, address: 000 Hotdog way, Hotdog HD, 12345 } ]
По какой-то причине аргументы были для меня той странной частью JavaScript, которая просто не до конца зацепила меня. Я не знаю, почему я зависаю каждый раз, когда мне нужно его определить, но с некоторой помощью я узнал, что первый аргумент в функции обратного вызова метода итерации представляет отдельный элемент в массиве. И я понял, что мне нужно еще больше использовать console.log в своей практике, потому что если бы я использовал console.log в качестве аргумента, я бы знал, что работаю с объектом. Эта одна часть информации сделала исправление, которое мне нужно было сделать более ясным.
Поэтому я дал аргументу более подходящее имя (место), а затем использовал его для доступа к свойству имени внутри.
До:
let searchResults = placesArray.filter(function (name) { return name.includes(searchTerm); })
После:
let searchResults = placesArray.filter(function (place, index) { return place.name.includes(searchTerm); })
Добавление второго аргумента (индекса) поможет мне на следующем шаге.
Тестирование
Чтобы проверить, все ли работает, я изучил отличный способ использования console.log при переборе массива.
console.log(`For iteration ${index}, does ${place.name} include ${searchTerm}. The answer is ${place.name.includes(searchTerm)}`);
Что в моем случае регистрируется:
Для итерации 0 включает ли Hotdog hut хот-дог. Ответ неверный
Почему оно было ложным? Потому что я набрал хот-дог вместо хот-дог. Чувствительность к регистру. Поэтому, чтобы не усложнять поиск, я изучил распространенное решение: использование метода .toLowerCase.
let searchResults = placesArray.filter(function (place, index) { const lowerName = place.name.toLowerCase(); const lowerSearch = searchTerm.toLowerCase(); console.log(`For iteration ${index}, does ${lowerName} include ${lowerSearch}. The answer is ${lowerName.includes(lowerSearch)}`); return lowerName.includes(lowerSearch); })
Таким образом, как свойства имени (из массива), так и значение в строке поиска будут преобразованы в строчные версии самих себя, и это означает, что больше не нужно беспокоиться о чувствительности к регистру. :) И когда я проверил, все ли работает, вот что я получил:
Для итерации 0 включает ли хот-дог хот-дог. Ответ правильный
Так приятно.