Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/387.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaScript:如何创建对象并对这些属性进行过滤?_Javascript_Html_Json_Filter - Fatal编程技术网

JavaScript:如何创建对象并对这些属性进行过滤?

JavaScript:如何创建对象并对这些属性进行过滤?,javascript,html,json,filter,Javascript,Html,Json,Filter,我有一个JavaScript数组,像这样的房子 { "homes" : [{ "home_id" : "1", "address" : "321 Main St", "city" : "Dallas", "state" : "TX", "zip" : "75201", "price"

我有一个JavaScript数组,像这样的房子

{
    "homes" : [{
        "home_id"         : "1",
        "address"         : "321 Main St",
        "city"            : "Dallas",
        "state"           : "TX",
        "zip"             : "75201",
        "price"           : "925",
        "sqft"            : "1100",
        "year_built"      : "2008",
        "account_type_id" : "2",
        "num_of_beds"     : "2",
        "num_of_baths"    : "2.0",
        "geolat"          : "32.779625",
        "geolng"          : "-96.786064",
        "photo_id"        : "14",
        "photo_url_dir"   : "\/home_photos\/thumbnail\/2009\/06\/10\/"
    }],
    ..........
}
我想提供3种不同的搜索方法

如何返回此homes area数组的子集,该数组具有:

  • X和Y之间的
    价格
  • 浴室
    >=Z
  • 卧室的#==A或==B或==C
例如,我将如何创建psuedo代码,如:

homes.filter {price >= 150000, price <= 400000, bathrooms >= 2.5, bedrooms == 1 | bedrooms == 3}
homes.filter{price>=150000,price=2.5,卧室==1 |卧室==3}
查看库中的函数。即使您不使用该库,您也可以查看代码并了解它们是如何完成您试图完成的任务的

编辑:以下是一些代码:

 function filter(houses, filters) // pass it filters object like the one in @J-P's answer
 {
      retArr = $.grep(houses, 
           function(house)
           {
                for(var filter in filters)
                {
                     function test = filters[filter];
                     if(!test(house)) return false;
                }
                return true;
           });

      return retArr;
 }

我假设您需要能够在homes数组上调用filter direction的语法,以生成一个只包含filter接受结果的新数组

使用对象原型在接受参数过滤器散列的数组对象上定义过滤器函数。然后,您可以轻松地使用该散列生成并返回与所需属性匹配的新的home数组。

看看JSONPath

类似于jsonPath(json,“$…homes[?(@.price给你:

var filteredArray = filter(myBigObject.homes, {

    price: function(value) {
        value = parseFloat(value);
        return value >= 150000 && value <= 400000;
    },

    num_of_baths: function(value) {
        value = parseFloat(value);
        return value >= 2.5;
    },

    num_of_beds: function(value) {
        value = parseFloat(value);
        return value === 1 || value === 3;
    }

});
Array.prototype.select=函数(过滤器){
如果(!filter)返回此;
var result=[],item=null;
for(var i=0;i=z和&inArray(项目编号[a、b、c])之间返回;
});
}
函数介于(值、最小值、最大值)之间{

return value>=min&&value我喜欢这个问题,所以我想尝试一下。一种“链式”的代码风格怎么样,在这种风格中,您拥有的对象返回自己,一种类似于一些JavaScript DOM框架的代码

我正在调用您的对象
MyObj

MyObj.filter('home.price >= 150000')
     .filter('home.price <= 400000')
     .filter('home.num_of_baths >= 2.5')
     .filter('home.num_of_beds == 1 || home.bedrooms == 3');
MyObj.filter('home.price>=150000')
.filter('home.price=2.5')
.filter('home.num_of_beds==1 | | home.beddooms==3');
这是源代码,这个例子有效

var MyObj = {
    filter : function(rule_expression) {
        var tmpHomes = [];
        var home = {};
        for(var i=0;i<this.homes.length;i++) {
            home = this.homes[i];
            if (eval(rule_expression)) {
                tmpHomes.push(home);
            }
        }
        this.homes = tmpHomes;
        return this;
    },
    homes: [
    {
        "home_id"         : 1,
        "address"         : "321 Main St",
        "city"            : "Dallas",
        "state"           : "TX",
        "zip"             : "75201",
        "price"           : 300000,
        "sqft"            : 1100,
        "year_built"      : 2008,
        "account_type_id" : 2,
        "num_of_beds"     : 1,
        "num_of_baths"    : 2.5,
        "geolat"          : 32.779625,
        "geolng"          : -96.786064,
        "photo_id"        : "14",
        "photo_url_dir"   : "\/home_photos\/thumbnail\/2009\/06\/10\/foo.jpg"
    },
    {
        "home_id"         : 2,
        "address"         : "555 Hello World Way",
        "city"            : "Dallas",
        "state"           : "TX",
        "zip"             : "75201",
        "price"           : 200000,
        "sqft"            : 900,
        "year_built"      : 1999,
        "account_type_id" : 2,
        "num_of_beds"     : 1,
        "num_of_baths"    : 1.0,
        "geolat"          : 32.779625,
        "geolng"          : -96.786064,
        "photo_id"        : "14",
        "photo_url_dir"   : "\/home_photos\/thumbnail\/2009\/06\/10\/foo.jpg"
    },
    {
        "home_id"         : 3,
        "address"         : "989 Foo St",
        "city"            : "Dallas",
        "state"           : "TX",
        "zip"             : "75201",
        "price"           : 80000,
        "sqft"            : 1100,
        "year_built"      : 2003,
        "account_type_id" : 2,
        "num_of_beds"     : 3,
        "num_of_baths"    : 3,
        "geolat"          : 32.779625,
        "geolng"          : -96.786064,
        "photo_id"        : "14",
        "photo_url_dir"   : "\/home_photos\/thumbnail\/2009\/06\/10\/foo.jpg"
    },
    {
        "home_id"         : 4,
        "address"         : "1560 Baz Rd",
        "city"            : "Dallas",
        "state"           : "TX",
        "zip"             : "75201",
        "price"           : 100000,
        "sqft"            : 1100,
        "year_built"      : 2008,
        "account_type_id" : 2,
        "num_of_beds"     : 3,
        "num_of_baths"    : 1.5,
        "geolat"          : 32.779625,
        "geolng"          : -96.786064,
        "photo_id"        : "14",
        "photo_url_dir"   : "\/home_photos\/thumbnail\/2009\/06\/10\/foo.jpg"
    }
    ]
};
var MyObj={
过滤器:函数(规则\表达式){
变量tmpHomes=[];
var home={};
for(var i=0;iJavascript 1.6(FF,基于Webkit)具有内置功能,因此无需重新发明轮子

result = homes.
  filter(function(p) { return p.price >= 150000 }).
  filter(function(p) { return p.price <= 400000 }).
  filter(function(p) { return p.bathrooms >= 2.5 }) etc
result=homes。
过滤器(函数(p){返回p.price>=150000})。
过滤器(函数(p){返回p.price=2.5})等
有关msie回退的信息,请参见。

该库对于这些任务非常有效。它在存在本机JavaScript命令时使用这些命令。我使用该库成功地获得了许多迭代循环

另外,最新版本是可链接的,就像jQuery一样。

o=({
o = ({
'homes' : 
[{
    "home_id"         : "1",
    "address"         : "321 Main St",
    "city"            : "Dallas",
    "state"           : "TX",
    "zip"             : "75201",
    "price"           : "20000",
    "sqft"            : "1100",
    "year_built"      : "2008",
    "account_type_id" : "2",
    "num_of_beds"     : "3",
    "num_of_baths"    : "3.0",
    "geolat"          : "32.779625",
    "geolng"          : "-96.786064",
    "photo_id"        : "14",
    "photo_url_dir"   : "\/home_photos\/thumbnail\/2009\/06\/10\/"
}
]})

Array.prototype.filterBy = function( by ) {
    outer: for ( 
    var i = this.length,
        ret = {},
        obj; 
        i--; 
    ) 
    {
    obj = this[i];
    for ( var prop in obj ) {

        if ( !(prop in by) ) continue

        if ( by[prop](obj[prop]) ) {
        ret[prop] = obj[prop]
        }

    }
    }

    return ret;
}

var result = o.homes.filterBy({
    price:function(price) {
        price = parseFloat(price)
        return price >= 15000 && price <=40000
    },
    num_of_baths:function(bathroom){
        bathroom = parseFloat(bathroom)
        return bathroom > 2.5
    },
    num_of_beds:function(bedroom){
        bedroom = parseFloat(bedroom)
        return bedroom === 1 || bedroom === 3
    }
});

for ( var p in result ) alert(p + '=' + result[p])
“家”: [{ “家庭id”:“1”, “地址”:“主街321号”, “城市”:“达拉斯”, “州”:“TX”, “zip”:“75201”, “价格”:“20000”, “sqft”:“1100”, “建造年份”:“2008年”, “帐户类型\ id”:“2”, “床位数”:“3”, “洗澡次数”:“3.0”, “geolat”:“32.779625”, “geolng”:“-96.786064”, “照片id”:“14”, “照片url目录”:“\/home\u photos\/thumbnail\/2009\/06\/10\/” } ]}) Array.prototype.filterBy=函数(按){ 外部:适用于( var i=此长度, ret={}, obj; 我--; ) { obj=这个[i]; 用于(obj中的var prop){ 如果(!(由代理)继续 如果(由[prop](obj[prop])){ ret[prop]=obj[prop] } } } 返回ret; } var结果=o.homes.filterBy({ 价格:功能(价格){ 价格=浮动(价格) 退货价格>=15000和价格2.5 }, 床的数量:功能(卧室){ 卧室=卧室(卧室) 返回卧室===1 | |卧室===3 } }); 对于(结果中的var p)警报(p+'='+结果[p])
我已经多次修改了这个答案,如果有人对这些修改感兴趣,人们可以查看wiki,但这是我提出的最终解决方案。它与这里发布的许多其他解决方案非常相似,关键区别在于我扩展了
数组。prototype
包装了
数组。prototype.filter
函数,以便在数组元素的范围内而不是在数组中计算测试语句

与直接使用
filter
方法相比,此解决方案的主要优势在于,它允许您编写测试
this[key]
值的通用测试。然后,您可以创建与特定测试关联的通用表单元素,并使用要筛选的对象的元数据(本例中包含)将表单元素的特定实例与键相关联。这不仅使代码更加可重用,而且我认为它使实际以编程方式构造查询更加直观。此外,因为您可以定义通用表单元素(例如,为不同的值选择一个multi-select,或为一个范围创建一组下拉列表),您还可以创建一个功能更强大的查询界面,在该界面中可以动态注入额外的表单元素,使用户可以创建复杂的自定义查询。代码分为以下几部分:

在做任何事情之前,您应该首先检查
filter
函数是否存在,并扩展
数组。prototype
,如果它没有其他解决方案中提到的那样。然后扩展
数组。prototype
以包装
filter
函数。我这样做是为了在有人想要的情况下,参数是可选的使用一个测试函数,由于某种原因,它不接受任何错误,我还尝试包含错误以帮助您实现代码:

Array.prototype.filterBy = function(testFunc, args)
{
    if(args == null || typeof args != 'object') args = [args];
    if(!testFunc || typeof testFunc != 'function') throw new TypeError('argument 0 must be defined and a function');
    return this.filter(function(elem)
        {
        return testFunc.apply(elem, args);
    });
};
这需要一个测试
o = ({
'homes' : 
[{
    "home_id"         : "1",
    "address"         : "321 Main St",
    "city"            : "Dallas",
    "state"           : "TX",
    "zip"             : "75201",
    "price"           : "20000",
    "sqft"            : "1100",
    "year_built"      : "2008",
    "account_type_id" : "2",
    "num_of_beds"     : "3",
    "num_of_baths"    : "3.0",
    "geolat"          : "32.779625",
    "geolng"          : "-96.786064",
    "photo_id"        : "14",
    "photo_url_dir"   : "\/home_photos\/thumbnail\/2009\/06\/10\/"
}
]})

Array.prototype.filterBy = function( by ) {
    outer: for ( 
    var i = this.length,
        ret = {},
        obj; 
        i--; 
    ) 
    {
    obj = this[i];
    for ( var prop in obj ) {

        if ( !(prop in by) ) continue

        if ( by[prop](obj[prop]) ) {
        ret[prop] = obj[prop]
        }

    }
    }

    return ret;
}

var result = o.homes.filterBy({
    price:function(price) {
        price = parseFloat(price)
        return price >= 15000 && price <=40000
    },
    num_of_baths:function(bathroom){
        bathroom = parseFloat(bathroom)
        return bathroom > 2.5
    },
    num_of_beds:function(bedroom){
        bedroom = parseFloat(bedroom)
        return bedroom === 1 || bedroom === 3
    }
});

for ( var p in result ) alert(p + '=' + result[p])
Array.prototype.filterBy = function(testFunc, args)
{
    if(args == null || typeof args != 'object') args = [args];
    if(!testFunc || typeof testFunc != 'function') throw new TypeError('argument 0 must be defined and a function');
    return this.filter(function(elem)
        {
        return testFunc.apply(elem, args);
    });
};
testSuite = {

     range : function(key, min, max)
     {
          var min = parseFloat(min);
          var max = parseFloat(max);
          var keyVal = parseFloat(this[key]);
          if(!min || !max|| !keyVal) return false;
          else return keyVal >= min && keyVal <= max;
     },

     distinct : function(key, values)
     {
          if(typeof key != 'string') throw new TypeError('key must be a string');
          if(typeof values != 'object') values = [values];
          var keyVal = this[key];
          if(keyVal == undefined) return false;


          for(var i in values)
          {
             var value = values[i];
             if(typeof value == 'function') continue;
             if(typeof value == 'string')
             {
                  if(keyVal.toString().toLowerCase() == value.toLowerCase()) return true;
                  else continue; 
             }
             else
             {
                 keyVal = parseFloat(keyVal);
                 value = parseFloat(value);
                 if(keyVal&&value&&(keyVal==value)) return true;
                 else continue;

            }
          }
          return false;
     }
};
 housesData.filterBy = function(tests)
 {
      ret = this.homes.slice(0);
      if(tests)
      {
           for(var i in tests)
           {
               var test = tests[i];
               if(typeof test != 'object') continue;
               if(!test.func || typeof test.func != 'function') throw new TypeError('argument 0 must be an array or object containing test objects, each with a key "func" of type function');
               else ret = ret.filterBy(test.func, test.args ? test.args : []);
           }
      }
      return ret;
 }
 result = housesData.filterBy([{func:range,args:['price','150000','400000'],
                      {func:distinct,args:['num_of_bedsf',[1, 2, 3]]}]);
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE html 
      PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:myNS="http://uri.for.your.schema" xml:lang="en" lang="en">
<head>
    <script src="jquery-1.3.2.js" type="text/javascript" language="javascript"></script>
    <script src="example.js" type="text/javascript" language="javascript"></script>
    <script type="text/javascript" language="javascript">
        runQuery = function(event)
        {
            var tests = [];
            $('#results').attr('value', '');;
            controls = $('#theForm > fieldset');
            for(var i = 0; i < controls.length ; i++)
            {
                var func;
                var args = [];
                control = controls.eq(i);
                func = testSuite[control.attr('myNS:type')];
                args.push(control.attr('myNS:key'));
                var inputs = $('input', control);
                for(var j=0; j< inputs.length; j++)
                {
                    args.push(inputs[j].value);
                }
                tests.push({func:func,args:args});
            }
            result = housesData.filterBy(tests);
            resultStr = '';
            for(var i = 0; i < result.length; i++)
            {
                resultStr += result[i]['home_id'];
                if(i < (result.length -1)) resultStr += ', ';
            }
            $('#results').attr('value', resultStr);
        }
    </script>
</head>
<body>
  <form id="theForm" action="javascript:null(0)">
    <fieldset myNS:type="range" myNS:key="price">
        <legend>Price:</legend>
        min: <input type="text" myNS:type="min"></input>
        max: <input type="text" myNS:type="max"></input>
    </fieldset>
    <fieldset myNS:type="distinct" myNS:key="num_of_beds">
        <legend>Bedrooms</legend>
        bedrooms: <input type="text" myNS:type="value"></input>
    </fieldset>
    <button onclick="runQuery(event);">Submit</button>
  </form>
  <textarea id="results"></textarea>
    </body>
 </html>
var filtered_results = obj.homes
    .filter(function (home)
    {
        return parseInt(home.price) >= document.getElementsByName('price_gt')[0].value;
    })
    .filter(function (home)
    {
        return parseInt(home.price) <= document.getElementsByName('price_lt')[0].value;
    })
    .filter(function (home)
    {
        return parseFloat(home.num_of_baths) >= document.getElementsByName('baths_gt')[0].value;
    });
var filtered_results = obj.homes.filter(function (home)
{
    return (
        parseInt(home.price) >= document.getElementsByName('price_gt')[0].value &&
        parseInt(home.price) <= document.getElementsByName('price_lt')[0].value &&
        parseFloat(home.num_of_baths) >= document.getElementsByName('baths_gt')[0].value
    );
});
var table = jOrder(data.homes)
    .index('price', ['price'], { ordered: true, grouped: true, type: jOrder.number });
var price_filtered = jOrder(table.where([{ price: { lower: 150000, upper: 400000 } }]))
    .index('bathrooms', ['num_of_baths'], { ordered: true, grouped: true, type: jOrder.number });
var bath_filtered = jOrder(price_filtered.where([{ num_of_baths: { lower: 2.5 } }]))
    .index('bedrooms', ['num_of_beds'], { grouped: true });
var filtered = jOrder(bath_filtered.where([{ num_of_beds: 1 }, { num_of_beds: 3 }]));