提问人:Steerpike 提问时间:7/1/2009 最后编辑:Alexander AbakumovSteerpike 更新时间:8/3/2023 访问量:1463467
按值对对象属性进行排序
Sorting object property by values
问:
如果我有一个 JavaScript 对象,例如:
var list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
有没有办法根据值对属性进行排序?所以我最终得到
list = {
"bar": 15,
"me": 75,
"you": 100,
"foo": 116
};
答:
根据定义,JavaScript 对象是无序的(请参阅 ECMAScript 语言 规范,第 8.6 节)。语言规范甚至不能保证,如果连续两次迭代一个对象的属性,它们第二次会以相同的顺序出现。
如果需要对内容进行排序,请使用数组和 Array.prototype.sort 方法。
评论
将它们移动到一个数组中,对该数组进行排序,然后将该数组用于您的目的。这里有一个解决方案:
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 = {
car: 300,
bike: 60,
motorbike: 200,
airplane: 1000,
helicopter: 400,
rocket: 8 * 60 * 60
};
const sortable = Object.entries(maxSpeed)
.sort(([,a],[,b]) => a-b)
.reduce((r, [k, v]) => ({ ...r, [k]: v }), {});
console.log(sortable);
在 ES10 中,你可以使用 Object.fromEntries()
将数组转换为对象。然后代码可以简化为:
const maxSpeed = {
car: 300,
bike: 60,
motorbike: 200,
airplane: 1000,
helicopter: 400,
rocket: 8 * 60 * 60
};
const sortable = Object.fromEntries(
Object.entries(maxSpeed).sort(([,a],[,b]) => a-b)
);
console.log(sortable);
评论
keys()
keys()
_.pairs
将对象转换为 [ [key1, value1], [key2, value2] ]。然后调用排序。然后调用它将其转回。_.object
为了完整起见,此函数返回对象属性的排序数组:
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) { return 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 在这里。此解决方案基于本文。
更新了用于对字符串进行排序的小提琴。您可以从中删除两个附加转换,以便进行区分大小写的字符串比较。.toLowerCase()
评论
我正在遵循 slebetman 给出的解决方案(阅读所有详细信息),但进行了调整,因为您的对象是非嵌套的。
// First create the array of keys/values so that we can sort it:
var sort_array = [];
for (var key in list) {
sort_array.push({key:key,value:list[key]});
}
// Now sort it:
sort_array.sort(function(x,y){return x.value - y.value});
// Now process that object with it:
for (var i=0;i<sort_array.length;i++) {
var item = list[sort_array[i].key];
// now do stuff with each item
}
我们不想复制整个数据结构,也不想在需要关联数组的地方使用数组。
这是与 bonna 执行相同操作的另一种方法:
var list = {"you": 100, "me": 75, "foo": 116, "bar": 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]);
下划线.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];
});
console.log(obj);
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js" integrity="sha256-qXBd/EfAdjOA2FGrGAG+b3YBn2tn5A6bhz+LSgYD96k=" crossorigin="anonymous"></script>
您的对象可以具有任意数量的属性,并且如果将对象放在数组中,则可以选择按所需的任何对象属性(数字或字符串)进行排序。考虑以下数组:
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
这可能是将其作为真实有序对象处理的简单方法。不知道它有多慢。使用 while 循环也可能更好。
Object.sortByKeys = function(myObj){
var keys = Object.keys(myObj)
keys.sort()
var sortedObject = Object()
for(i in keys){
key = keys[i]
sortedObject[key]=myObj[key]
}
return sortedObject
}
然后我从以下位置找到了这个反转函数: http://nelsonwells.net/2011/10/swap-object-key-and-values-in-javascript/
Object.invert = function (obj) {
var new_obj = {};
for (var prop in obj) {
if(obj.hasOwnProperty(prop)) {
new_obj[obj[prop]] = prop;
}
}
return new_obj;
};
所以
var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
var invertedList = Object.invert(list)
var invertedOrderedList = Object.sortByKeys(invertedList)
var orderedList = Object.invert(invertedOrderedList)
许多类似且有用的功能:https://github.com/shimondoodkin/groupbyfunctions/
function sortobj(obj)
{
var keys=Object.keys(obj);
var kva= keys.map(function(k,i)
{
return [k,obj[k]];
});
kva.sort(function(a,b){
if(a[1]>b[1]) return -1;if(a[1]<b[1]) return 1;
return 0
});
var o={}
kva.forEach(function(a){ o[a[0]]=a[1]})
return o;
}
function sortobjkey(obj,key)
{
var keys=Object.keys(obj);
var kva= keys.map(function(k,i)
{
return [k,obj[k]];
});
kva.sort(function(a,b){
k=key; if(a[1][k]>b[1][k]) return -1;if(a[1][k]<b[1][k]) return 1;
return 0
});
var o={}
kva.forEach(function(a){ o[a[0]]=a[1]})
return o;
}
ECMAScript 2017 引入了 Object.values / Object.entries
。顾名思义,前者将一个对象的所有值聚合到一个数组中,后者将整个对象聚合到一个数组中;Python 的等价物 dict.values() 和 dict.items
()。
[key, value]
这些功能使得将任何哈希值排序到有序对象中变得非常容易。截至目前,只有一小部分 JavaScript 平台支持它们,但您可以在 Firefox 47+ 上尝试一下。
编辑:现在所有现代浏览器都支持!
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]);
@marcusR答案的“箭头”版本供参考
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 = { you: 100, me: 75, foo: 116, bar: 15 };
const result =
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.entrys(根据评论更新)
const myObj = { you: 100, me: 75, foo: 116, bar: 15 };
const result = 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
sort()
Object.entries()
使用 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 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}
评论
好的,您可能知道,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}
同样这样,主对象不会被触及,我们实际上会得到一个新对象。
我还创建了下面的图像,以使功能步骤更加清晰,以防您需要对其进行一些更改以按照自己的方式工作:
评论
c: 3
c: 13
按值排序的对象 (DESC)
function sortObject(list) {
var sortable = [];
for (var key in list) {
sortable.push([key, list[key]]);
}
sortable.sort(function(a, b) {
return (a[1] > b[1] ? -1 : (a[1] < b[1] ? 1 : 0));
});
var orderedList = {};
for (var i = 0; i < sortable.length; i++) {
orderedList[sortable[i][0]] = sortable[i][1];
}
return orderedList;
}
var list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
var tmpList = {};
while (Object.keys(list).length) {
var key = Object.keys(list).reduce((a, b) => list[a] > list[b] ? a : b);
tmpList[key] = list[key];
delete list[key];
}
list = tmpList;
console.log(list); // { foo: 116, you: 100, me: 75, bar: 15 }
a = { b: 1, p: 8, c: 2, g: 1 }
Object.keys(a)
.sort((c,b) => {
return a[b]-a[c]
})
.reduce((acc, cur) => {
let o = {}
o[cur] = a[cur]
acc.push(o)
return acc
} , [])
输出 = [ { p: 8 }, { c: 2 }, { b: 1 }, { g: 1 } ]
以防万一,有人正在寻找保留对象(带有键和值),使用 @Markus R 的代码引用并@James Moran 注释,只需使用:
var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
var newO = {};
Object.keys(list).sort(function(a,b){return list[a]-list[b]})
.map(key => newO[key] = list[key]);
console.log(newO); // {bar: 15, me: 75, you: 100, foo: 116}
评论
map
forEach
在没有多个 for 循环的情况下对值进行排序(要按键排序,请将排序回调中的索引更改为“0”)
const list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
let sorted = Object.fromEntries(
Object.entries(list).sort( (a,b) => a[1] - b[1] )
)
console.log('Sorted object: ', sorted)
非常简短和简单!
var sortedList = {};
Object.keys(list).sort((a,b) => list[a]-list[b]).forEach((key) => {
sortedList[key] = list[key]; });
TypeScript(打字稿)
以下函数按值或值的属性对对象进行排序。如果不使用 TypeScript,则可以删除类型信息以将其转换为 JavaScript。
/**
* Represents an associative array of a same type.
*/
interface Dictionary<T> {
[key: string]: T;
}
/**
* Sorts an object (dictionary) by value or property of value and returns
* the sorted result as a Map object to preserve the sort order.
*/
function sort<TValue>(
obj: Dictionary<TValue>,
valSelector: (val: TValue) => number | string,
) {
const sortedEntries = Object.entries(obj)
.sort((a, b) =>
valSelector(a[1]) > valSelector(b[1]) ? 1 :
valSelector(a[1]) < valSelector(b[1]) ? -1 : 0);
return new Map(sortedEntries);
}
用法
var list = {
"one": { height: 100, weight: 15 },
"two": { height: 75, weight: 12 },
"three": { height: 116, weight: 9 },
"four": { height: 15, weight: 10 },
};
var sortedMap = sort(list, val => val.height);
JavaScript 对象中键的顺序无法保证,因此我将结果排序并作为保留排序顺序的对象返回。Map
如果要将其转换回 Object,可以执行以下操作:
var sortedObj = {} as any;
sortedMap.forEach((v,k) => { sortedObj[k] = v });
评论
const arrayOfObjects = [
{name: 'test'},
{name: 'test2'}
]
const order = ['test2', 'test']
const setOrder = (arrayOfObjects, order) =>
arrayOfObjects.sort((a, b) => {
if (order.findIndex((i) => i === a.name) < order.findIndex((i) => i === b.name)) {
return -1;
}
if (order.findIndex((i) => i === a.name) > order.findIndex((i) => i === b.name)) {
return 1;
}
return 0;
});
let toSort = {a:2323, b: 14, c: 799}
let sorted = Object.entries(toSort ).sort((a,b)=> a[1]-b[1])
输出:
[ [ "b", 14 ], [ "c", 799 ], [ "a", 2323 ] ]
我的解决方案与排序:
let list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
let sorted = Object.entries(list).sort((a,b) => a[1] - b[1]);
for(let element of sorted) {
console.log(element[0]+ ": " + element[1]);
}
<pre>
function sortObjectByVal(obj){
var keysSorted = Object.keys(obj).sort(function(a,b){return obj[b]-obj[a]});
var newObj = {};
for(var x of keysSorted){
newObj[x] = obj[x];
}
return newObj;
}
var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
console.log(sortObjectByVal(list));
</pre>
评论
有很多方法可以做到这一点,但由于我没有看到任何用途,所以我把它放在这里。也许它对某人来说似乎是有用的。reduce()
var list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
let result = Object.keys(list).sort((a,b)=>list[a]>list[b]?1:-1).reduce((a,b)=> {a[b]=list[b]; return a},{});
console.log(result);
感谢 @orad 在 TypeScript 中提供答案。现在,我们可以在 JavaScript 中使用下面的代码片段。
function sort(obj,valSelector) {
const sortedEntries = Object.entries(obj)
.sort((a, b) =>
valSelector(a[1]) > valSelector(b[1]) ? 1 :
valSelector(a[1]) < valSelector(b[1]) ? -1 : 0);
return new Map(sortedEntries);
}
const Countries = { "AD": { "name": "Andorra", }, "AE": { "name": "United Arab Emirates", }, "IN": { "name": "India", }}
// Sort the object inside object.
var sortedMap = sort(Countries, val => val.name);
// Convert to object.
var sortedObj = {};
sortedMap.forEach((v,k) => { sortedObj[k] = v }); console.log(sortedObj);
//Output: {"AD": {"name": "Andorra"},"IN": {"name": "India"},"AE": {"name": "United Arab Emirates"}}
按值对对象属性进行排序
const obj = { you: 100, me: 75, foo: 116, bar: 15 };
const keysSorted = Object.keys(obj).sort((a, b) => obj[a] - obj[b]);
const result = {};
keysSorted.forEach(key => { result[key] = obj[key]; });
document.write('Result: ' + JSON.stringify(result));
所需输出:
{"bar":15,"me":75,"you":100,"foo":116}
引用:
一个早已过时的问题的后续答案。我编写了两个函数,一个按键排序,另一个按值排序,并在两个函数中以排序形式返回对象。它也应该适用于字符串,因为这就是我发布此内容的原因(如果值不是数字,则在按值排序时遇到上述一些困难)。
const a = {
absolutely: "works",
entirely: 'zen',
best: 'player',
average: 'joe'
}
const prop_sort = obj => {
return Object.keys(obj)
.sort()
.reduce((a, v) => {
a[v] = obj[v];
return a;
}, {});
}
const value_sort = obj => {
const ret = {}
Object.values(obj)
.sort()
.forEach(val => {
const key = Object.keys(obj).find(key => obj[key] == val)
ret[key] = val
})
return ret
}
console.log(prop_sort(a))
console.log(value_sort(a))
这是实现此目的的另一种方法
var list = {
"you": 100,
"me": 75,
"foo": 116,
"bar": 15
};
const sortedByValue = Object.fromEntries(
Object.entries(list).sort((a, b) => {
return a[1] - b[1];
})
);
console.log(sortedByValue);
评论
Object.entries