#javascript #arrays #json #regex #nested
#javascript #массивы #json #регулярное выражение #вложенный
Вопрос:
Я пытаюсь выяснить, как получить доступ к вложенным массивам и отобразить их во внешнем JSON-файле.
В приведенном ниже примере «color» — это массив ровно с двумя разными цветами. В действительности я хотел бы, чтобы это число менялось между одним и несколькими цветами, но для получения результата я использовал ровно два цвета.
Прямо сейчас: если выполнить поиск, например, «bl», программа вернет все имена, начинающиеся с «bl», но только цвета с индексом 0. Никогда не указывайте 1.
Желаемый результат: пользователь должен иметь возможность искать цвета, независимо от того, где в «цветном» массиве находится цвет.
Я искал здесь на SO и в других местах, но я не смог перенести эту информацию в свой собственный проект. Ближе всего к решению, к которому я пришел, была реструктуризация. Таким образом, я мог бы получить цвет индекса 0 и второй цвет в качестве объекта при консоли.запишите его. Когда я попытался с помощью for-loop, я получил только индекс 0, даже когда я изменил 0 на I.
Мой JSON:
{
"items": [
{
"gender": "female",
"firstName": "bonnie",
"lastName": "parker",
"_comment": "HERE ARE THE COLORS",
"color": ["pink", "purple"],
"image":{
"url":"/images/bonnie.jpg"
}
},
{
"gender": "female",
"firstName": "stephanie",
"lastName": "st.Clair",
"color": ["yellow", "orange"],
"image":{
"url":"/images/stephanie.jpg"
}
},
{
"gender": "male",
"firstName": "al",
"lastName": "capone",
"color": ["green", "black"],
"image":{
"url":"/images/al.jpg"
}
},
{
"gender": "male",
"firstName": "john",
"lastName": "dillinger",
"color": ["blue", "red"],
"image":{
"url":"/images/john.jpg"
}
},
{
"gender": "female",
"firstName": "ma",
"lastName": "baker",
"color": ["green", "white"],
"image":{
"url":"/images/ma.jpg"
}
},
{
"gender": "male",
"firstName": "clyde",
"lastName": "barrow",
"color": ["yellow", "gray"],
"image":{
"url":"/images/clyde.jpg"
}
},
{
"gender": "male",
"firstName": "carlo",
"lastName": "gambino",
"color": ["pink", "blue"],
"image":{
"url":"/images/carlo.jpg"
}
},
{
"gender": "male",
"firstName": "jesse",
"lastName": "james",
"color": ["gray", "purple"],
"image":{
"url":"/images/jesse.jpg"
}
},
{
"gender": "male",
"firstName": "benjamin 'bugsy'",
"lastName": "siegel",
"color": ["blue", "purple"],
"image":{
"url":"/images/bugsy.jpg"
}
}
]
}
Мой JS
const searchBtn = document.querySelector('.button');
const searchText = document.querySelector('.search');
const matchDOM = document.querySelector('.matchOutput');
const clearBtn = document.querySelector('.clear-search');
/** Get the search-item */
const getItem = async searchText => {
try {
const res = await fetch('/items.json')
const data = await res.json();
let product = data.items;
let matches = product.filter(item => {
const regex = new RegExp(`^${searchText}`, 'gi');
return item.firstName.match(regex) || item.lastName.match(regex)
|| item.gender.match(regex) || item.color[0].match(regex) /** HERE IS THE PROBLEM **/
});
if (searchText.length === 0) {
matches = [];
matchDOM.innerHTML = '';
}
itemOutput(matches);
} catch (err) {
console.log(err)
}
}
/** Display the search-item */
const itemOutput = matches => {
const myHtml = matches.map(match => `
<div class="search-group">
<img src=${match.image.url} alt="product" />
<div class="text-info">
<h2>Name: ${match.firstName}</h2>
<h3>LastName: ${match.lastName}</h3>
<h4>${match.gender}</h4>
</div>
<h4 class="colors">${match.color}</h4>
</div>
`)
myHtml.sort();
matchDOM.innerHTML = myHtml;
}
/** Search via Enter-click */
searchText.addEventListener("keyup", function(event) {
if (event.keyCode === 13) {
event.preventDefault();
searchBtn.click();
}
});
/** Search via Button-click */
searchBtn.addEventListener('click', () => {
getItem(searchText.value)
})
/** Clear search */
clearBtn.addEventListener('click', () => {
matchDOM.innerHTML = '';
})
Любая помощь приветствуется. Спасибо!
Ответ №1:
Насколько я понимаю, ваша проблема в том, что в вашем коде поисковый запрос проверяется только по первой записи цвета, а не по всем записям цвета. Если я прав, решением было бы изменить последний термин в you ИЛИ-chain в строке 15 с
… || item.color[0].match(regex)
Для
… || item.color.filter(c => c.match(regex)).length !== 0
объяснение
Ваше последнее выражение проверяет только, соответствует ли первый цвет регулярному выражению. Приведенная выше замена фильтрует все цвета по результату сопоставления и просто проверяет, действительно ли один или несколько цветов совпадают, проверяя длину возвращаемого массива.
Ответ №2:
Вместо item.color[0].match(regex)
этого примените регулярное выражение к строковому представлению вместо: ("" item.color).match(colorregex)
. Для сопоставления цветов используйте определенное регулярное выражение, чтобы обеспечить соответствие цветов, если i>0 соответственно:
const colorregex = new RegExp(`.*(^|,)${searchText}.*`, 'gi');
Комментарии:
1. регулярное выражение содержало маркер, поэтому строка совпадает только тогда, когда строковое представление начинается с searchstring . Я соответствующим образом отредактировал свой ответ