如何根据属性过滤对象数组?

IT技术 javascript
2020-12-26 15:49:19

我有以下房地产住宅对象的 JavaScript 数组:

var json = {
    'homes': [{
            "home_id": "1",
            "price": "925",
            "sqft": "1100",
            "num_of_beds": "2",
            "num_of_baths": "2.0",
        }, {
            "home_id": "2",
            "price": "1425",
            "sqft": "1900",
            "num_of_beds": "4",
            "num_of_baths": "2.5",
        },
        // ... (more homes) ...     
    ]
}

var xmlhttp = eval('(' + json + ')');
homes = xmlhttp.homes;

我想做的是能够对对象执行过滤器以返回“home”对象的子集。

例如,我想根据能够过滤:pricesqftnum_of_beds,和num_of_baths

我如何在 JavaScript 中执行类似下面的伪代码的操作:

var newArray = homes.filter(
    price <= 1000 & 
    sqft >= 500 & 
    num_of_beds >=2 & 
    num_of_baths >= 2.5 );

请注意,语法不必与上述完全相同。这只是一个例子。

6个回答

您可以使用以下Array.prototype.filter方法:

var newArray = homes.filter(function (el) {
  return el.price <= 1000 &&
         el.sqft >= 500 &&
         el.num_of_beds >=2 &&
         el.num_of_baths >= 2.5;
});

现场示例:

这种方法是新的ECMAScript 第 5 版标准的一部分,几乎可以在所有现代浏览器上找到。

对于 IE,您可以包含以下兼容性方法:

if (!Array.prototype.filter) {
  Array.prototype.filter = function(fun /*, thisp*/) {
    var len = this.length >>> 0;
    if (typeof fun != "function")
      throw new TypeError();

    var res = [];
    var thisp = arguments[1];
    for (var i = 0; i < len; i++) {
      if (i in this) {
        var val = this[i];
        if (fun.call(thisp, val, i, this))
          res.push(val);
      }
    }
    return res;
  };
}
@JGreig:只是一个注释,表明可以传递一个可选参数,该参数没有直接指定,因为 ECMA 标准明确指出该方法应该只需要一个参数 ( Array.prototype.filter.length == 1;)。当您使用第二个参数时,它将用作this回调函数中值。
2021-02-07 15:49:19
@CMS,我已经用实时网站更新了我的原始帖子。如果你能看一下代码就太好了。我真的,真的很感激。提前致谢
2021-02-17 15:49:19
@CMS,您确定此代码有效吗?这将返回一个空数组,即使我将价格设置得非常高并且平方英尺/床位/浴室非常低。你确定这段代码有效吗?
2021-02-22 15:49:19
@CMS 如果答案包括返回一个新数组,而不修改原始数组这一事实,那就太好了。即使在提供的链接中提到了这一点,我发现没有这个的答案是不完整或不准确的
2021-02-28 15:49:19
@JGreig:是的,它有效,你应该检查你的标准,也许你可以在Pastie.orgjsbin.com 中发布一个更完整的 JSON 示例以及你用来过滤的标准,所以我可以更好地帮助你。
2021-03-05 15:49:19

您可以尝试使用 jLinq 之类的框架 - 以下是使用 jLinq 的代码示例

var results = jLinq.from(data.users)
.startsWith("first", "a")
.orEndsWith("y")
.orderBy("admin", "age")
.select();

有关更多信息,您可以点击链接http://www.hugoware.net/projects/jlinq

我很惊讶没有人发布单行回复:

const filteredHomes = json.homes.filter(x => x.price <= 1000 && x.sqft >= 500 && x.num_of_beds >=2 && x.num_of_baths >= 2.5);

...只是为了让您可以更轻松地阅读:

const filteredHomes = json.homes.filter( x => 
  x.price <= 1000 && 
  x.sqft >= 500 && 
  x.num_of_beds >=2 && 
  x.num_of_baths >= 2.5
);
可能是因为它与仅使用箭头函数的CMS 的答案相同
2021-02-17 15:49:19

我更喜欢 Underscore 框架。它建议对对象进行许多有用的操作。你的任务:

var newArray = homes.filter(
    price <= 1000 & 
    sqft >= 500 &
    num_of_beds >=2 & 
    num_of_baths >= 2.5);

可以像这样覆盖:

var newArray = _.filter (homes, function(home) {
    return home.price<=1000 && sqft>=500 && num_of_beds>=2 && num_of_baths>=2.5;
});

希望对你有用!

这个下划线是如何工作的,它到底是什么意思?
2021-02-09 15:49:19
刚刚发现underscore-querygithub.com/davidgtonge/underscore-query)它使用类似 MongoDB 的语法来查询 javascript 数组。所以在这里你会使用_.query(homes, {price: {$lt:1000}, sqft: {$gte: 500}, num_of_beds: {$gte:2}, num_of_baths: {$gte: 2.5}}
2021-02-12 15:49:19

这是使用 jquery MAP 功能在 IE8 中工作正常的工作小提琴

http://jsfiddle.net/533135/Cj4j7/

json.HOMES = $.map(json.HOMES, function(val, key) {
    if (Number(val.price) <= 1000
            && Number(val.sqft) >= 500
            && Number(val.num_of_beds) >=2
            && Number(val.num_of_baths ) >= 2.5)
        return val;
});