我有一个大型数据集(存储在数组中的400 - 4,000个对象),我试图通过用户选择的字段过滤它们。
现在我正在使用此功能,在另一个SO问题上找到:
var sort = function (prop, arr) {
prop = prop.split('.');
var len = prop.length;
arr.sort(function (a, b) {
var i = 0;
while( i < len ) {
a = a[prop[i]];
b = b[prop[i]];
i++;
}
if (a < b) {
return -1;
} else if (a > b) {
return 1;
} else {
return 0;
}
});
return arr;
};
示例数据 - 我想按friends
计数对对象进行排序:
var data = [
{
name: 'Jim',
friends: {
count: 20,
url: 'http://foo.com'
}
},{
name: 'Lucy',
},{
name: 'Phil',
friends: {
count: 450,
url: 'http://moo.com'
}
}
];
注意&#34;露西&#34;没有friends
对象 - 所以当我运行sort('friends.count', data);
时,脚本会中断。
理想情况下,我喜欢那些没有我排序的属性放在数组末尾的对象。关于如何实现这一点的任何想法?
答案 0 :(得分:3)
例如,
var data = [
{
name: 'Jim',
friends: {
count: 20,
url: 'http://foo.com'
}
},{
name: 'Lucy',
},{
name: 'Phil',
friends: {
count: 450,
url: 'http://moo.com'
}
}
];
safeGet = function(obj, prop, defaultValue) {
try {
return obj[prop]
} catch(e) {
return defaultValue
}
}
data.sort(function(x, y) {
return (
safeGet(x.friends, 'count', Infinity) -
safeGet(y.friends, 'count', Infinity));
});
document.write("<pre>" + JSON.stringify(data,0,3));
&#13;
如果整个属性链(friends.count
)是动态的,请更改safeGet
,以便迭代道具列表:
var data = [
{
name: 'Jim',
friends: {
count: 20,
url: 'http://foo.com'
}
},{
name: 'Lucy',
},{
name: 'Phil',
friends: {
count: 450,
url: 'http://moo.com'
}
}
];
safeGet = function(obj, props, defaultValue) {
try {
return props.split('.').reduce(function(obj, p) {
return obj[p];
}, obj);
} catch(e) {
return defaultValue
}
}
data.sort(function(x, y) {
return (
safeGet(x, 'friends.count', Infinity) -
safeGet(y, 'friends.count', Infinity));
});
document.write("<pre>" + JSON.stringify(data,0,3));
&#13;
如果您希望没有朋友的人先行,而不是最后,请将Infinity
更改为-Infinity
。
答案 1 :(得分:0)
您的功能可以修改以检查是否存在属性:
var sort = function (prop, arr) {
prop = prop.split('.');
var len = prop.length;
arr.sort(function (a, b) {
var i = 0;
var key;
while( i < len ) {
key = prop[i];
if(!a.hasOwnProperty(key)) return 1;
if(!b.hasOwnProperty(key)) return -1;
a = a[key];
b = b[key];
i++;
}
if (a < b) {
return -1;
} else if (a > b) {
return 1;
} else {
return 0;
}
});
return arr;
};
这样它就会起作用。我为这个例子做了一个jsbin。
@ georg的答案不适用于动态选择的属性。