You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 17:49:52