отображение вложенного массива в файле json с помощью javascript

#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 . Я соответствующим образом отредактировал свой ответ