如果我有一个 JavaScript 对象,例如:
var list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
有没有办法根据价值对属性进行排序?所以我最终得到
list = {
"bar": 15,
"me": 75,
"you": 100,
"foo": 116
};
Object.entries
的答案,这是自 ES2017 以来最干净、最易读的最新技术:stackoverflow.com/a/37607084/245966
将它们移动到一个数组中,对该数组进行排序,然后将该数组用于您的目的。这是一个解决方案:
let maxSpeed = {
car: 300,
bike: 60,
motorbike: 200,
airplane: 1000,
helicopter: 400,
rocket: 8 * 60 * 60
};
let sortable = [];
for (var vehicle in maxSpeed) {
sortable.push([vehicle, maxSpeed[vehicle]]);
}
sortable.sort(function(a, b) {
return a[1] - b[1];
});
// [["bike", 60], ["motorbike", 200], ["car", 300],
// ["helicopter", 400], ["airplane", 1000], ["rocket", 28800]]
一旦你有了数组,你可以按照你喜欢的顺序从数组中重建对象,从而完全实现你的目标。这适用于我所知道的所有浏览器,但它取决于实现的怪癖,并且可能随时中断。你永远不应该对 JavaScript 对象中元素的顺序做出假设。
let objSorted = {}
sortable.forEach(function(item){
objSorted[item[0]]=item[1]
})
在 ES8 中,您可以使用 Object.entries()
将对象转换为数组:
const maxSpeed = { 汽车:300,自行车:60,摩托车:200,飞机:1000,直升机:400,火箭:8 * 60 * 60 }; const sortable = Object.entries(maxSpeed) .sort(([,a],[,b]) => ab) .reduce((r, [k, v]) => ({ ...r, [k ]: v }), {});控制台.log(可排序);
在 ES10 中,您可以使用 Object.fromEntries()
将数组转换为对象。那么代码可以简化为:
const maxSpeed = { 汽车:300,自行车:60,摩托车:200,飞机:1000,直升机:400,火箭:8 * 60 * 60 }; const sortable = Object.fromEntries(Object.entries(maxSpeed).sort(([,a],[,b]) => ab));控制台.log(可排序);
我们不想复制整个数据结构,或者在需要关联数组的地方使用数组。
这是与 bonna 做同样事情的另一种方法:
var list = {“你”:100,“我”:75,“富”:116,“酒吧”:15}; keysSorted = Object.keys(list).sort(function(a,b){return list[a]-list[b]}) console.log(keysSorted); // bar,me,you,foo
keysSorted
是一个数组!不是对象!
.map(key => list[key]);
添加到排序的末尾,它将返回整个对象,而不仅仅是键
您的对象可以具有任意数量的属性,如果您将对象放入数组中,您可以选择按您想要的任何对象属性(数字或字符串)进行排序。考虑这个数组:
var arrayOfObjects = [
{
name: 'Diana',
born: 1373925600000, // Mon, Jul 15 2013
num: 4,
sex: 'female'
},
{
name: 'Beyonce',
born: 1366832953000, // Wed, Apr 24 2013
num: 2,
sex: 'female'
},
{
name: 'Albert',
born: 1370288700000, // Mon, Jun 3 2013
num: 3,
sex: 'male'
},
{
name: 'Doris',
born: 1354412087000, // Sat, Dec 1 2012
num: 1,
sex: 'female'
}
];
按出生日期排序,从大到小
// use slice() to copy the array and not just make a reference
var byDate = arrayOfObjects.slice(0);
byDate.sort(function(a,b) {
return a.born - b.born;
});
console.log('by date:');
console.log(byDate);
按名称分类
var byName = arrayOfObjects.slice(0);
byName.sort(function(a,b) {
var x = a.name.toLowerCase();
var y = b.name.toLowerCase();
return x < y ? -1 : x > y ? 1 : 0;
});
console.log('by name:');
console.log(byName);
substr
出第一个字符;否则 Diana
和 Debra
具有未定义的顺序。此外,您的 byDate
排序实际上使用 num
,而不是 born
。
x.localeCompare(y)
localCompare
看起来是一个非常有用的功能!请注意,并非所有浏览器都支持它 - IE 10 及更低版本、Safari Mobile 9 及更低版本。
ECMAScript 2017 引入了 Object.values / Object.entries
。顾名思义,前者将一个对象的所有值聚合成一个数组,后者将整个对象聚合成一个[key, value]
数组的数组; Python 的 dict.values()
和 dict.items()
等价物。
这些功能使将任何散列排序为有序对象变得非常容易。到目前为止,只有一小部分 JavaScript 平台支持它们,但您可以在 Firefox 47+ 上试用。
编辑:现在受 all modern browsers! 支持
let obj = {"you": 100, "me": 75, "foo": 116, "bar": 15};
let entries = Object.entries(obj);
// [["you",100],["me",75],["foo",116],["bar",15]]
let sorted = entries.sort((a, b) => a[1] - b[1]);
// [["bar",15],["me",75],["you",100],["foo",116]]
Sorting JavaScript Object by property value
?您误解了我认为的问题,因为您要更改原始对象而不是从中创建新数组。
let sorted = Object.entries(obj).sort((a, b) => a[1] - b[1]);
为了完整起见,此函数返回对象属性的排序数组:
function sortObject(obj) {
var arr = [];
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) {
arr.push({
'key': prop,
'value': obj[prop]
});
}
}
arr.sort(function(a, b) { return a.value - b.value; });
//arr.sort(function(a, b) { a.value.toLowerCase().localeCompare(b.value.toLowerCase()); }); //use this to sort as strings
return arr; // returns array
}
var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
var arr = sortObject(list);
console.log(arr); // [{key:"bar", value:15}, {key:"me", value:75}, {key:"you", value:100}, {key:"foo", value:116}]
JSFiddle with the code above is here。此解决方案基于 this article。
Updated fiddle for sorting strings is here. 您可以从中删除两个额外的 .toLowerCase()
转换,以进行区分大小写的字符串比较。
@marcusR 的 answer 的“箭头”版本供参考
var myObj = { you: 100, me: 75, foo: 116, bar: 15 };
keysSorted = Object.keys(myObj).sort((a, b) => myObj[a] - myObj[b]);
alert(keysSorted); // bar,me,you,foo
更新:2017 年 4 月 这将返回上面定义的已排序 myObj
对象。
const myObj = {你:100,我:75,foo:116,bar:15}; const 结果 = Object.keys(myObj) .sort((a, b) => myObj[a] - myObj[b]) .reduce( (_sortedObj, key) => ({ ..._sortedObj, [key]: myObj[key] }), {} ); document.write(JSON.stringify(result));
更新:2021 年 3 月 - 具有排序功能的 Object.entries(根据评论更新)
const myObj = {你:100,我:75,foo:116,bar:15}; const 结果 = Object .entries(myObj) .sort((a, b) => a[1] - b[1]) .reduce((_sortedObj, [k,v]) => ({ ..._sortedObj, [k]: v }), {}) document.write(JSON.stringify(result));
var myObj = {"1": {"Value": 40}, "2": {"Value": 10}, "3": {"Value": 30}, "4": {"Value": 20}};
entries
。根据标准,对象是属性的无序集合。好吧,这意味着如果您在按属性值或其他任何内容对新对象进行排序后尝试构造新对象,则属性键顺序再次变为未定义。例如,Chrome 默认对属性键进行排序,因此每次尝试对它们进行不同的排序都是无用的。您唯一的机会是根据您的订购偏好获得“索引”并相应地遍历原始对象。
Object.entries()
上使用 sort()
JavaScript 对象根据定义是无序的(请参阅 ECMAScript Language Specification,第 8.6 节)。语言规范甚至不保证,如果您连续两次迭代对象的属性,它们第二次将以相同的顺序出现。
如果您需要订购物品,请使用数组和 Array.prototype.sort 方法。
好的,你可能知道,javascript 有 sort() 函数,可以对数组进行排序,但没有对象......
因此,在这种情况下,我们需要以某种方式获取键数组并对它们进行排序,这就是 api 在大多数情况下为您提供数组中的对象的原因,因为 Array 具有比对象字面量更多的本机函数,无论如何,快速独奏使用 Object.key ,它返回一个对象键数组,我在下面创建了 ES6 函数,它为你完成了这项工作,它在 javascript 中使用本机 sort() 和 reduce() 函数:
function sortObject(obj) {
return Object.keys(obj)
.sort().reduce((a, v) => {
a[v] = obj[v];
return a; }, {});
}
现在你可以像这样使用它:
let myObject = {a: 1, c: 3, e: 5, b: 2, d: 4};
let sortedMyObject = sortObject(myObject);
检查 sortedMyObject ,您可以看到按如下键排序的结果:
{a: 1, b: 2, c: 3, d: 4, e: 5}
同样这样,主对象不会被触及,我们实际上得到了一个新对象。
我还创建了下面的图像,以使功能步骤更加清晰,以防您需要对其进行一些更改以按照自己的方式工作:
https://i.stack.imgur.com/iJ6dX.png
c: 3
更改为 c: 13
,您会看到它分崩离析。
var list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
function sortAssocObject(list) {
var sortable = [];
for (var key in list) {
sortable.push([key, list[key]]);
}
// [["you",100],["me",75],["foo",116],["bar",15]]
sortable.sort(function(a, b) {
return (a[1] < b[1] ? -1 : (a[1] > b[1] ? 1 : 0));
});
// [["bar",15],["me",75],["you",100],["foo",116]]
var orderedList = {};
for (var idx in sortable) {
orderedList[sortable[idx][0]] = sortable[idx][1];
}
return orderedList;
}
sortAssocObject(list);
// {bar: 15, me: 75, you: 100, foo: 116}
使用 ES6 更新:如果您担心要迭代一个排序对象(这就是我想您希望对象属性排序的原因),您可以使用 Map 对象。
您可以按排序顺序插入(键、值)对,然后执行 for..of
循环将保证让它们按照您插入的顺序循环
var myMap = new Map();
myMap.set(0, "zero");
myMap.set(1, "one");
for (var [key, value] of myMap) {
console.log(key + " = " + value);
}
// 0 = zero
// 1 = one
for-in
或 Object.keys
遵守,但它被定义为由 Object.getOwnPropertyNames
和其他用于访问属性的新方法遵守名称数组。所以这是另一种选择。
Map
你实际上有一个可以按排序顺序存储的数据结构(对你的数据进行排序,循环遍历它并将其存储在地图中),而你不是保证与对象。
非常简短!
var sortedList = {};
Object.keys(list).sort((a,b) => list[a]-list[b]).forEach((key) => {
sortedList[key] = list[key]; });
对没有多个 for 循环的值进行排序(按键排序,将排序回调中的索引更改为“0”)
常量列表 = {“你”:100,“我”:75,“富”:116,“酒吧”:15 }; let sorted = Object.fromEntries( Object.entries(list).sort( (a,b) => a[1] - b[1] ) ) console.log('Sorted object: ', sorted)
Underscore.js 或 Lodash.js 用于高级数组或对象排序
var data = { "models": { "LTI": [ "TX" ], "Carado": [ "A", "T", "A(пасс)", "A(груз)", "T(пасс )”、“T(груз)”、“A”、“T”]、“SPARK”:[“SP110C 2”、“sp150r 18”]、“Autobianchi”:[“A112”]}}; var arr = [], obj = {}; for (var i in data.models) { arr.push([i, _.sortBy(data.models[i], function(el) { return el; })]); } arr = _.sortBy(arr, function(el) { return el[0]; }); _.map(arr, function(el) { return obj[el[0]] = el[1]; });控制台.log(obj);
keys()
仅受 IE9+ (和其他现代浏览器)支持,如果这值得关注的话。此外,keys()
排除了元素原型链中的可枚举属性(与 for..in 不同)——但这通常更可取。_.pairs
将对象转换为 [ [key1, value1], [key2, value2] ]。然后调用 sort 。然后调用_.object
将其转回。