JavaScript移除数组重复键:保留每个键最后一次输入值
问题:过滤数组保留每个输入框的最新输入值
我有6个输入框,用来捕获用户输入并存入数组,用于筛选表格。使用keyup事件把输入内容推入query数组,但每次按键都会添加当前输入字符串,导致同一个键对应多个重复的历史值。现在需要移除重复的键,只保留每个输入框的最后一次输入值。
输入框渲染代码
var operatorFilter = document.querySelector("#operatorFilters"); operatorFilter.innerHTML = `<input type="text" id="idFilter" onkeyup='idFilter(this, "id")' placeholder="Operator ID"></input> <input type="text" id="operatorFilter" onkeyup='idFilter(this, "operatorName")' placeholder="Operator Name"></input> <input type="text" id="facilityFilter" onkeyup='idFilter(this, "facility")' placeholder="Facility"></input> <input type="text" id="pieceCountFilter" onkeyup='idFilter(this, "piece")' placeholder="Piece Count"></input> <input type="text" id="jobCountFilter" onkeyup='idFilter(this, "job")' placeholder="Job Count"></input> <input type="text" id="dateFilter" onkeyup='idFilter(this, "date")' placeholder="Date Filter"></input>`
输入处理代码
var query = [] function idFilter(userInput, inputID){ var inputHolder = [] if(inputID == "id"){ inputHolder = ({operatorID:userInput.value}) } else if(inputID == "operatorName"){ inputHolder = ({operatorFirst:userInput.value}, {operatorLast:userInput.value}) } else if(inputID == "facility"){ inputHolder = ({facility:userInput.value}) } else if(inputID == "piece"){ inputHolder = ({pieceCount:userInput.value}) } else if(inputID == "job"){ inputHolder = ({jobCount:userInput.value}) } else if(inputID == "date"){ inputHolder = ({date:userInput.value}) } console.log(inputHolder) query.push(inputHolder) console.log(query) }
当前控制台输出
0: {operatorID: '3'} 1: {operatorID: '36'} 2: {operatorID: '368'} 3: {operatorID: '3689'} 4: {operatorLast: 'B'} 5: {operatorLast: 'B'} 6: {operatorLast: 'Bo'} 7: {operatorLast: 'Bob'} 8: {operatorLast: 'Bob '} 9: {operatorLast: 'Bob S'} 10: {operatorLast: 'Bob S'} 11: {operatorLast: 'Bob Smi'} 12: {operatorLast: 'Bob Smi'} 13: {operatorLast: 'Bob Smit'} 14: {operatorLast: 'Bob Smith'} 15: {date: '08'} 16: {date: '08/'} 17: {date: '08/2'} 18: {date: '08/25'} 19: {date: '08/25/'} 20: {date: '08/25/2'} 21: {date: '08/25/20'} 22: {date: '08/25/202'} 23: {date: '08/25/2024'}
尝试过的无效方法
function testFilter(){ query = query.filter((value, index, self) => index === self.findIndex((t) => ( t.place === value.place && t.name === value.name )) ) console.log(query) }
结果对比
- 预期结果:
0: {operatorID: '3689'} 1: {operatorLast: 'Bob Smith'} 2: {date: '08/25/2024'} - 实际结果:
0: {operatorID: '3'}
解决方案
核心问题是每次keyup都往数组里新增对象,而非更新对应键的已有值。没必要先push再过滤,直接维护最新值更高效。
方案1:改用对象存储(推荐)
把query改成对象,每次输入直接覆盖对应键的值,天然保留最新值,后续需要数组格式时再转换:
// 将数组改为对象存储 var query = {}; function idFilter(userInput, inputID){ switch(inputID){ case "id": query.operatorID = userInput.value; break; case "operatorName": // 修复原代码逗号运算符的问题,合并为一个对象存储 query.operatorFirst = userInput.value; query.operatorLast = userInput.value; break; case "facility": query.facility = userInput.value; break; case "piece": query.pieceCount = userInput.value; break; case "job": query.jobCount = userInput.value; break; case "date": query.date = userInput.value; break; } // 如需数组格式,用Object.values(query)转换 console.log("当前筛选参数:", query); console.log("数组格式结果:", Object.values(query)); }
方案2:强制保留数组结构
如果必须用数组存储,每次输入前先删除数组中对应键的旧项,再添加新值:
var query = []; function idFilter(userInput, inputID){ let inputHolder; let targetKeys; switch(inputID){ case "id": inputHolder = {operatorID: userInput.value}; targetKeys = ["operatorID"]; break; case "operatorName": inputHolder = {operatorFirst: userInput.value, operatorLast: userInput.value}; targetKeys = ["operatorFirst", "operatorLast"]; break; case "facility": inputHolder = {facility: userInput.value}; targetKeys = ["facility"]; break; case "piece": inputHolder = {pieceCount: userInput.value}; targetKeys = ["pieceCount"]; break; case "job": inputHolder = {jobCount: userInput.value}; targetKeys = ["jobCount"]; break; case "date": inputHolder = {date: userInput.value}; targetKeys = ["date"]; break; } // 移除数组中已存在对应键的旧项 query = query.filter(item => { return !targetKeys.some(key => item.hasOwnProperty(key)); }); // 添加最新输入值 query.push(inputHolder); console.log(query); }
原方法失败原因
你写的testFilter里用了t.place === value.place && t.name === value.name,但你的对象中根本没有place和name这两个键,过滤逻辑完全不匹配,所以得不到正确结果。
内容的提问来源于stack exchange,提问作者MrGovenator
相关产品推荐
相关产品推荐

