Javascript:如何基于属性过滤对象数组?

时间:2022-05-30 15:57:22

I have the following JavaScript array of real estate home objects:

我有以下房地产住宅对象的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;

What I would like to do is be able to perform a filter on the object to return a subset of "home" objects.

我想做的是能够对对象执行筛选,以返回“home”对象的子集。

For example, I want to be able to filter based on: price, sqft, num_of_beds, and num_of_baths.

例如,我希望能够基于:price、sqft、num_of_beds和num_of_baths进行筛选。

Question: How can I perform something in JavaScript like the pseudo-code below:

问:如何使用JavaScript执行如下伪代码:

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

Note, the syntax does not have to be exactly like above. This is just an example.

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

9 个解决方案

#1


483  

You can use the Array.prototype.filter method:

您可以使用Array.prototype。筛选方法:

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

Live Example:

生活例子:

var obj = {
    '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) ...     
    ]
};
// (Note that because `price` and such are given as strings in your object,
// the below relies on the fact that <= and >= with a string and number
// will coerce the string to a number before comparing.)
var newArray = obj.homes.filter(function (el) {
  return el.price <= 1000 &&
         el.sqft >= 500 &&
         el.num_of_beds >= 2 &&
         el.num_of_baths >= 1.5; // Changed this so a home would match
});
console.log(newArray);

This method is part of the new ECMAScript 5th Edition standard, and can be found on almost all modern browsers.

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

For IE, you can include the following method for compatibility:

对于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;
  };
}

#2


26  

You can try using framework like jLinq - following is a code sample of using jLinq

您可以尝试使用jLinq这样的框架——以下是使用jLinq的代码示例

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

For more information you can follow the link http://www.hugoware.net/projects/jlinq

要了解更多信息,请访问http://www.hugoware.net/projects/jlinq

#3


22  

I prefer the Underscore framework. It suggests many useful operations with objects. Your task:

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

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

can be overwriten like:

可以overwriten像:

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

Hope it will be useful for you!

希望它对你有用!

#4


9  

here is the working fiddle which works fine in IE8 using jquery MAP function

这是一个使用jquery MAP函数在IE8中工作的小提琴

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

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;
});

#5


7  

You could do this pretty easily - there are probably many implementations you can choose from, but this is my basic idea (and there is probably some format where you can iterate over an object with jQuery, I just cant think of it right now):

你可以很容易地做到这一点——可能有很多实现可以选择,但这是我的基本想法(而且可能有某种格式可以用jQuery对一个对象进行迭代,我现在想不出来):

function filter(collection, predicate)
{
    var result = new Array();
    var length = collection.length;

    for(var j = 0; j < length; j++)
    {
        if(predicate(collection[j]) == true)
        {
             result.push(collection[j]);
        }
    }

    return result;
}

And then you could invoke this function like so:

然后你可以这样调用这个函数:

filter(json, function(element)
{
    if(element.price <= 1000 && element.sqft >= 500 && element.num_of_beds > 2 && element.num_of_baths > 2.5)
        return true;

    return false;
});

This way, you can invoke the filter based on whatever predicate you define, or even filter multiple times using smaller filters.

通过这种方式,您可以基于定义的任何谓词调用过滤器,甚至可以使用更小的过滤器多次过滤。

#6


6  

You can use jQuery.grep() since jQuery 1.0:

您可以使用jQuery.grep(),因为jQuery 1.0:

$.grep(homes, function (h) {
  return h.price <= 1000
    && h.sqft >= 500
    && h.num_of_beds >= 2
    && h.num_of_baths >= 2.5
});

#7


3  

You can implement a filter method yourself that meets your needs, here is how:

您可以自己实现一个满足您的需求的筛选方法,如下所示:

function myfilter(array, test){
    var passedTest =[];
    for (var i = 0; i < array.length; i++) {
       if(test( array[i]))
          passedTest.push(array[i]);
    }

    return passedTest;
}

var passedHomes = myfilter(homes,function(currentHome){
     return ((currentHome.price <= 1000 )&& (currentHome.sqft >= 500 )&&(currentHome.num_of_beds >=2 )&&(currentHome.num_of_baths >= 2.5));
});

Hope, it helps!

希望,它可以帮助!

#8


1  

Or you can simply use $.each (which also works for objects, not only arrays) and build a new array like so:

或者你可以使用$。每个(也适用于对象,不只是数组)并构建一个新的数组,如下所示:

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) ...     
        {
            "home_id": "3-will-be-matched",
            "price": "925",
            "sqft": "1000",
            "num_of_beds": "2",
            "num_of_baths": "2.5",
        },
    ]
}

var homes = [];
$.each(json.homes, function(){
    if (this.price <= 1000
        && this.sqft >= 500
        && this.num_of_beds >= 2
        && this.num_of_baths >= 2.5
    ) {
        homes.push(this);
    }
});

#9


1  

You should check out OGX.List which has built in filtering methods and extends the standard javascript array (and also grouping, sorting and finding). Here's a list of operators it supports for the filters:

你应该看看OGX。列表,它内置了过滤方法并扩展了标准javascript数组(以及分组、排序和查找)。下面是它为过滤器所支持的操作符列表:

'eq' //Equal to
'eqjson' //For deep objects, JSON comparison, equal to
'neq' //Not equal to
'in' //Contains
'nin' //Doesn't contain
'lt' //Lesser than
'lte' //Lesser or equal to
'gt' //Greater than
'gte' //Greater or equal to
'btw' //Between, expects value to be array [_from_, _to_]
'substr' //Substring mode, equal to, expects value to be array [_from_, _to_, _niddle_]
'regex' //Regex match

You can use it this way

你可以用这种方法

  let list = new OGX.List(your_array);
  list.addFilter('price', 'btw', 100, 500);
  list.addFilter('sqft', 'gte', 500);
  let filtered_list = list.filter();

And you can add as many filters as you want (one per property only)

你可以添加任意多的过滤器(仅一个属性)

#1


483  

You can use the Array.prototype.filter method:

您可以使用Array.prototype。筛选方法:

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

Live Example:

生活例子:

var obj = {
    '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) ...     
    ]
};
// (Note that because `price` and such are given as strings in your object,
// the below relies on the fact that <= and >= with a string and number
// will coerce the string to a number before comparing.)
var newArray = obj.homes.filter(function (el) {
  return el.price <= 1000 &&
         el.sqft >= 500 &&
         el.num_of_beds >= 2 &&
         el.num_of_baths >= 1.5; // Changed this so a home would match
});
console.log(newArray);

This method is part of the new ECMAScript 5th Edition standard, and can be found on almost all modern browsers.

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

For IE, you can include the following method for compatibility:

对于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;
  };
}

#2


26  

You can try using framework like jLinq - following is a code sample of using jLinq

您可以尝试使用jLinq这样的框架——以下是使用jLinq的代码示例

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

For more information you can follow the link http://www.hugoware.net/projects/jlinq

要了解更多信息,请访问http://www.hugoware.net/projects/jlinq

#3


22  

I prefer the Underscore framework. It suggests many useful operations with objects. Your task:

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

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

can be overwriten like:

可以overwriten像:

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

Hope it will be useful for you!

希望它对你有用!

#4


9  

here is the working fiddle which works fine in IE8 using jquery MAP function

这是一个使用jquery MAP函数在IE8中工作的小提琴

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

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;
});

#5


7  

You could do this pretty easily - there are probably many implementations you can choose from, but this is my basic idea (and there is probably some format where you can iterate over an object with jQuery, I just cant think of it right now):

你可以很容易地做到这一点——可能有很多实现可以选择,但这是我的基本想法(而且可能有某种格式可以用jQuery对一个对象进行迭代,我现在想不出来):

function filter(collection, predicate)
{
    var result = new Array();
    var length = collection.length;

    for(var j = 0; j < length; j++)
    {
        if(predicate(collection[j]) == true)
        {
             result.push(collection[j]);
        }
    }

    return result;
}

And then you could invoke this function like so:

然后你可以这样调用这个函数:

filter(json, function(element)
{
    if(element.price <= 1000 && element.sqft >= 500 && element.num_of_beds > 2 && element.num_of_baths > 2.5)
        return true;

    return false;
});

This way, you can invoke the filter based on whatever predicate you define, or even filter multiple times using smaller filters.

通过这种方式,您可以基于定义的任何谓词调用过滤器,甚至可以使用更小的过滤器多次过滤。

#6


6  

You can use jQuery.grep() since jQuery 1.0:

您可以使用jQuery.grep(),因为jQuery 1.0:

$.grep(homes, function (h) {
  return h.price <= 1000
    && h.sqft >= 500
    && h.num_of_beds >= 2
    && h.num_of_baths >= 2.5
});

#7


3  

You can implement a filter method yourself that meets your needs, here is how:

您可以自己实现一个满足您的需求的筛选方法,如下所示:

function myfilter(array, test){
    var passedTest =[];
    for (var i = 0; i < array.length; i++) {
       if(test( array[i]))
          passedTest.push(array[i]);
    }

    return passedTest;
}

var passedHomes = myfilter(homes,function(currentHome){
     return ((currentHome.price <= 1000 )&& (currentHome.sqft >= 500 )&&(currentHome.num_of_beds >=2 )&&(currentHome.num_of_baths >= 2.5));
});

Hope, it helps!

希望,它可以帮助!

#8


1  

Or you can simply use $.each (which also works for objects, not only arrays) and build a new array like so:

或者你可以使用$。每个(也适用于对象,不只是数组)并构建一个新的数组,如下所示:

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) ...     
        {
            "home_id": "3-will-be-matched",
            "price": "925",
            "sqft": "1000",
            "num_of_beds": "2",
            "num_of_baths": "2.5",
        },
    ]
}

var homes = [];
$.each(json.homes, function(){
    if (this.price <= 1000
        && this.sqft >= 500
        && this.num_of_beds >= 2
        && this.num_of_baths >= 2.5
    ) {
        homes.push(this);
    }
});

#9


1  

You should check out OGX.List which has built in filtering methods and extends the standard javascript array (and also grouping, sorting and finding). Here's a list of operators it supports for the filters:

你应该看看OGX。列表,它内置了过滤方法并扩展了标准javascript数组(以及分组、排序和查找)。下面是它为过滤器所支持的操作符列表:

'eq' //Equal to
'eqjson' //For deep objects, JSON comparison, equal to
'neq' //Not equal to
'in' //Contains
'nin' //Doesn't contain
'lt' //Lesser than
'lte' //Lesser or equal to
'gt' //Greater than
'gte' //Greater or equal to
'btw' //Between, expects value to be array [_from_, _to_]
'substr' //Substring mode, equal to, expects value to be array [_from_, _to_, _niddle_]
'regex' //Regex match

You can use it this way

你可以用这种方法

  let list = new OGX.List(your_array);
  list.addFilter('price', 'btw', 100, 500);
  list.addFilter('sqft', 'gte', 500);
  let filtered_list = list.filter();

And you can add as many filters as you want (one per property only)

你可以添加任意多的过滤器(仅一个属性)