按子属性(可能缺少)对对象的 javascript 数组进行排序
Sort javascript array of objects by child properties (which may be missing)
我有一个大型数据集(存储在数组中的 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'
}
}
];
请注意"Lucy"没有friends
对象 - 因此当我运行sort('friends.count', data);
时,脚本中断。
理想情况下,我希望将没有我正在排序的属性的对象放在数组的末尾。关于如何实现这一目标的任何想法?
例如,
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));
如果整个属性链 ( friends.count
) 是动态的,请更改safeGet
以便它迭代 props 列表:
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));
如果您希望没有朋友的人先走,而不是最后走,请将Infinity
更改为-Infinity
。
可以修改函数以检查属性是否存在:
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的答案不适用于动态选择的属性。
相关文章:
- Chrome开发工具(如何知道我在调用哪个javascript对象)
- 循环遍历以数组为值的Javascript对象
- 从ajax请求中获取javascript对象
- 如何从对象的原型方法访问JavaScript对象属性
- 将XML转换为普通的旧JavaScript对象
- 通过引用传递JavaScript对象
- javascript对象操作:根据指定条件选择属性
- Javascript对象类在单击时打开窗口进行颜色选择,并在更改时替换对象背景颜色
- 如何在异步函数中使用javascript对象
- 临时Javascript对象
- 如何在ASP中为用户控件添加Javascript对象网
- 使用数组向下搜索Javascript对象
- Rails将JavaScript对象存储到Model的有效方式
- JavaScript对象不是从原型链继承的
- 如何创建具有默认值的JavaScript对象字段?(AngularJS模型相关)
- SetInterval在javascript对象中表现怪异
- Javascript 对象和 this 关键字
- 如何在不知道关键字的情况下访问javascript对象值
- 在 JavaScript 对象中设置要使用的运算符的属性
- 如何搜索JavaScript对象并更改值