【问题标题】:How to filter array when object key value is in array当对象键值在数组中时如何过滤数组
【发布时间】:2016-06-19 10:59:49
【问题描述】:

我有一个数组模型如下:

records:[{
    "empid":1,
    "fname": "X",
    "lname": "Y"
},
{
    "empid":2,
    "fname": "A",
    "lname": "Y"
},
{
    "empid":3,
    "fname": "B",
    "lname": "Y"
},
{
    "empid":4,
    "fname": "C",
    "lname": "Y"
},
{
    "empid":5,
    "fname": "C",
    "lname": "Y"
}
]

现在我有一个 empid 的 [1,4,5] 数组。

所以现在我需要过滤包含第二个中所有键的第一个数组。

输出:

records:[{
    "empid":1,
    "fname": "X",
    "lname": "Y"
},
{
    "empid":4,
    "fname": "C",
    "lname": "Y"
},
{
    "empid":5,
    "fname": "C",
    "lname": "Y"
}
]

我可以在angular 中使用forEach 循环来做到这一点,但因为我的模型对象中有100 多条记录。我需要关于如何以更好的方式处理此问题的建议。

我正在考虑创建一个自定义过滤器,但您对此有何看法。(如果是,请提供实现此目的的示例代码)。

【问题讨论】:

标签: javascript angularjs angular-filters


【解决方案1】:

您可以使用Array.prototype.filter()

var data = { records : [{ "empid": 1, "fname": "X", "lname": "Y" }, { "empid": 2, "fname": "A", "lname": "Y" }, { "empid": 3, "fname": "B", "lname": "Y" }, { "empid": 4, "fname": "C", "lname": "Y" }, { "empid": 5, "fname": "C", "lname": "Y" }] }
var empIds = [1,4,5]
var filteredArray = data.records.filter(function(itm){
  return empIds.indexOf(itm.empid) > -1;
});

filteredArray = { records : filteredArray };

如果​callBack​返回一个​true​值,则传递给特定callBack的​itm​将被过滤掉。你可以阅读更多关于它的信息here。​​​​​​​

【讨论】:

  • 这真的很简单@Rajaprabhu,但是在大数据(大约500-1000)长度数组上执行此操作时与性能相关的任何信息,
  • @KrishnaAditya 与for循环非常相似,内部数据将通过使用for循环进行迭代,但以一种有效的方式。这使代码更具可读性和可维护性。
【解决方案2】:

这是一个使用临时对象的快速解决方案。

var records = [{ "empid": 1, "fname": "X", "lname": "Y" }, { "empid": 2, "fname": "A", "lname": "Y" }, { "empid": 3, "fname": "B", "lname": "Y" }, { "empid": 4, "fname": "C", "lname": "Y" }, { "empid": 5, "fname": "C", "lname": "Y" }],
    empid = [1, 4, 5],
    object = {},
    result;

records.forEach(function (a) {
    object[a.empid] = a;
});

result = empid.map(function (a) {
    return object[a];
});
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');

【讨论】:

  • 是的,这看起来还不错。更有可能作为哈希键查找,我也会检查这个。谢谢@尼娜
【解决方案3】:

您可以使用Array#filter 函数和附加数组来存储排序值;

var recordsSorted = []

ids.forEach(function(e) {
    recordsSorted.push(records.filter(function(o) {
        return o.empid === e;
    }));
});

console.log(recordsSorted);

结果:

[ [ { empid: 1, fname: 'X', lname: 'Y' } ],
  [ { empid: 4, fname: 'C', lname: 'Y' } ],
  [ { empid: 5, fname: 'C', lname: 'Y' } ] ]

【讨论】:

    【解决方案4】:

    最快的方式(需要额外的内存):

    var empid=[1,4,5]
    var records = [{ "empid": 1, "fname": "X", "lname": "Y" }, { "empid": 2, "fname": "A", "lname": "Y" }, { "empid": 3, "fname": "B", "lname": "Y" }, { "empid": 4, "fname": "C", "lname": "Y" }, { "empid": 5, "fname": "C", "lname": "Y" }] ;
    
    var empIdObj={};
    
    empid.forEach(function(element) {
    empIdObj[element]=true;
    });
    
    var filteredArray=[];
    
    records.forEach(function(element) {
    if(empIdObj[element.empid])
        filteredArray.push(element)
    });
    

    【讨论】:

      【解决方案5】:

      2019 年使用 ES6:

      const ids = [1, 4, 5],
        data = {
          records: [{
            "empid": 1,
            "fname": "X",
            "lname": "Y"
          }, {
            "empid": 2,
            "fname": "A",
            "lname": "Y"
          }, {
            "empid": 3,
            "fname": "B",
            "lname": "Y"
          }, {
            "empid": 4,
            "fname": "C",
            "lname": "Y"
          }, {
            "empid": 5,
            "fname": "C",
            "lname": "Y"
          }]
        };
      
      
      data.records = data.records.filter( i => ids.includes( i.empid ) );
      
      console.info( data );

      【讨论】:

      • 一些解释的话会极大地增加你的答案对 JavaScript 初学者的价值。 ;)
      【解决方案6】:

      如果您的输入数组中有键值对,我使用:

      .filter(
                this.multi_items[0] != null && store.state.isSearchBox === false
                  ? item =>
                      _.map(this.multi_items, "value").includes(item["wijknaam"])
                  : item => item["wijknaam"].includes("")
              );
      

      其中输入数组是 multi_items 为:[{"text": "bla1", "value": "green"}, {"text": etc. etc.}]

      _.map 是一个 lodash 函数。

      【讨论】:

        【解决方案7】:

        老办法。很多人可能讨厌这种方式,但我仍然有很多时间发现在我看来这仍然更好。

        输入:

        var records = [{
            "empid":1,
            "fname": "X",
            "lname": "Y"
        },
        {
            "empid":2,
            "fname": "A",
            "lname": "Y"
        },
        {
            "empid":3,
            "fname": "B",
            "lname": "Y"
        },
        {
            "empid":4,
            "fname": "C",
            "lname": "Y"
        },
        {
            "empid":5,
            "fname": "C",
            "lname": "Y"
        }
        ]
        
        var newArr = [1,4,5];
        

        代码:

        var newObj = [];
        for(var a = 0 ; a < records.length ; a++){
         if(newArr.indexOf(records[a].empid) > -1){
          newObj.push(records[a]);
         }
        }
        

        indexOf() 方法返回可以在数组中找到给定元素的第一个索引,如果不存在,则返回 -1。

        参考 - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf

        输出:

        [{
            "empid": 1,
            "fname": "X",
            "lname": "Y"
        }, {
            "empid": 4,
            "fname": "C",
            "lname": "Y"
        }, {
            "empid": 5,
            "fname": "C",
            "lname": "Y"
        }]
        

        【讨论】:

          【解决方案8】:
          var records = [{
           "empid":1,
           "fname": "X",
           "lname": "Y"
          },
          {
           "empid":2,
           "fname": "A",
           "lname": "Y"
          }
          
          ]
          
          
          let search="A"
           
          let values= Result.filter(item =>
               keys.some(key => 
                   String(item[key]).toLowerCase().includes(search.toLowerCase()) 
               )
           );
          

          对象数组中的多键搜索,例如(empid,fname,lname)

          【讨论】:

          • 请添加更多详细信息以扩展您的答案,例如工作代码或文档引用。
          • 您可以使用javascript/html/css snippet 访问CTRL+M 使代码能够运行。
          猜你喜欢
          • 2020-09-29
          • 1970-01-01
          • 2020-01-12
          • 2022-01-23
          • 2022-07-20
          • 2021-04-23
          • 1970-01-01
          • 2021-11-27
          • 2022-12-12
          相关资源
          最近更新 更多