JavaScript filter处理对象数组字符串字段报错及替代实现方案
问题原因
你仅修改了render渲染阶段的取值逻辑,但是data.filter的筛选逻辑仍将数组元素当作纯字符串处理,现在数组元素是包含name字段的对象,需要先取出name属性再做匹配校验。
修复方案
只需要修改filter回调内的匹配逻辑即可,修改后的完整JS代码如下:
const allListItems = document.getElementById("all-list-items"); fetch('json-data.json') .then(response => response.json()) .then(function (data) { render(data) document.getElementById("searchInput").addEventListener("input", event => { const value = /** @type {string} **/ (event.target.value).trim(); // 搜索内容为空时直接返回全量数据 if (!value) { render(data); return; } const terms = value.toLowerCase().split(/[ -]/); // 核心改动:先取item.name再做匹配 render(data.filter(item => terms .map(term => item.name.toLowerCase().includes(term)) .reduce((result, entry) => result && entry))); }); }) .catch(err => console.log('error: ' + err)) function render(things) { let html = ''; for (const thing of things) { html += `<li class="names">${thing.name}</li>`; } allListItems.innerHTML = html || 'No match'; }
filter方法的替代实现
如果你不想用filter链式调用,可以用普通for循环手动筛选数据,逻辑完全等价:
// 替代filter的手动筛选逻辑 const filteredList = []; const terms = value.toLowerCase().split(/[ -]/); for (let i = 0; i < data.length; i++) { const currentItem = data[i]; const itemName = currentItem.name.toLowerCase(); let isMatch = true; for (let j = 0; j < terms.length; j++) { if (!itemName.includes(terms[j])) { isMatch = false; break; } } if (isMatch) { filteredList.push(currentItem); } } render(filteredList);
内容的提问来源于stack exchange,提问作者Muneeba Dilawaze
相关产品推荐
相关产品推荐

