【问题标题】:How to filter a javascript object array with variable parameters如何过滤带有可变参数的javascript对象数组
【发布时间】:2013-06-10 13:04:16
【问题描述】:

我想根据对象的属性选择对象,但并不总是相同的属性。换句话说:

arr = [
    { name: "joe",   age21: 1 },
    { name: "nick",  age21: 0 },
    { name: "blast", age21: 1 }
];

arr.filter(function(item) {
    return (item.name === "nick" && item.age21 === 1);
});

但有时我只想过滤名称,例如:

arr.filter(function(item) {
    return (item.name === "nick");
});

我想要做的是概括这一点,以便可以将参数列表传递给函数。我想出了以下方法,但速度很慢,我想知道是否有更好的方法:

filterParams = function(arr, params) {
    var new_array = arr.filter(function(item) {
        var select = 1
        for(obj in params) { //create the filter criteria based on varying set of parameters
            var select = select && params[obj] === item[obj];
        }
        return select;
    });
    return new_array;
}

然后你可以调用它: filterParams(arr, {name: "nick", age21: 1});

或与: filterParams(arr, {name: "nick"});

无论哪种方式都可以。

如果您想知道,我这样做是因为我有不同的数据集,我想通过相同的例程运行,因此过滤器属性需要通用化,以便我可以过滤特定于每个数据集的属性.

谢谢!

【问题讨论】:

  • “但它很慢” 你是如何衡量的?我们在谈论多少个元素?您可能已经可以通过将obj 设为本地而不是全局并在已经不匹配时停止比较属性(即break 退出循环)来改进代码。如果您只是想改进代码,这个问题可能更适合codereview.stackexchange.com
  • 看起来很复杂的天哪。你确定你要这么做吗?为什么不直接写一个filter_by_namefilter_by_agefilter_by_age_and_name(或者让它们可链接)。这看起来像是过早优化的情况。
  • 哦,如果它失败了,那是个好主意。我想我说它是因为似乎必须有一种方法可以做到这一点,这是标准做法,但我不知道它是什么。我会把它移到那里。谢谢!

标签: javascript filter


【解决方案1】:

这是一个函数式方法,它适用于给定对象的任意数量的属性:

function filter(arr, criteria) {
  return arr.filter(function(obj) {
    return Object.keys(criteria).every(function(c) {
      return obj[c] == criteria[c];
    });
  });
}

例如:

var arr = [
  { name: 'Steve', age: 18, color: 'red' },
  { name: 'Louis', age: 21, color: 'blue' }, //*
  { name: 'Mike', age: 20, color: 'green' },
  { name: 'Greg', age: 21, color: 'blue' }, //*
  { name: 'Josh', age: 18, color: 'red' }
];

console.log(filter(arr, { age: 21, color: 'blue' }));
//^ {age:21, color:'blue', name:'Louis}
//  {age:21, color:'blue', name:'Greg'}

不确定您的性能问题,但这应该没问题。

编辑:您可以使用正则表达式使其更强大,如下所示:

function filter(arr, criteria) {
  return arr.filter(function(obj) {
    return Object.keys(criteria).every(function(c) {
      return new RegExp(criteria[c]).test(obj[c]);
    });
  });
}

console.log(filter(arr, { age: /^2\d$/, color: /^(red|blue)$/ }));
//^ Louis, Greg                --^-- twenty-something
//                                               ----^---- red OR blue

【讨论】:

  • 同样添加了小提琴。高级用于特定的数字检查和忽略大小写的搜索。在这里小提琴:jsfiddle.net/6s3thmgL/38
猜你喜欢
  • 1970-01-01
  • 2020-07-21
  • 1970-01-01
  • 2021-04-23
  • 1970-01-01
  • 2012-11-15
  • 1970-01-01
  • 2018-11-22
相关资源
最近更新 更多