JavaScript:如何创建对象并对这些属性进行过滤?
我有一个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"
{
"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
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 }]));