按值对对象属性进行排序

Sorting object property by values

提问人:Steerpike 提问时间:7/1/2009 最后编辑:Alexander AbakumovSteerpike 更新时间:8/3/2023 访问量:1463467

问:

如果我有一个 JavaScript 对象,例如:

var list = {
  "you": 100, 
  "me": 75, 
  "foo": 116, 
  "bar": 15
};

有没有办法根据值对属性进行排序?所以我最终得到

list = {
  "bar": 15, 
  "me": 75, 
  "you": 100, 
  "foo": 116
};
JavaScript 排序 属性 对象

评论

5赞 Sampson 7/1/2009
不仅是“排序”,更重要的是对数字进行排序。数字不受 Javascripts Array.sort() 方法的影响,这意味着您不仅需要找到对属性进行排序的方法,还必须编写自己的函数来比较数值。
237赞 Govind Rai 10/29/2016
在阅读答案之前:答案是否定的。在 ECMAScript 中,对象属性的排序是非标准的。永远不要对 JavaScript 对象中元素的顺序做出假设。Object 是属性的无序集合。下面的答案向您展示了如何借助数组“使用”排序的属性,但实际上绝不会更改对象本身的属性顺序。所以,不,这是不可能的。即使您构建了一个具有预排序属性的对象,也不能保证它们将来会以相同的顺序显示。请继续阅读:)。
11赞 ProblemsOfSumit 12/19/2016
然而,@GovindRai,在现实世界的前端应用程序中,我们循环使用 ID 作为键的对象集合,如果将其转换为 HTML 模板,顺序很重要。你说他们没有顺序,我说他们有我在当前浏览器中 console.logging 它们时看到的顺序。并且该订单可以重新排序。只要你环过他们,他们就有了订单。
9赞 T.J. Crowder 1/1/2017
@GovindRai:现在有一种方法可以在规范中按指定顺序访问属性。这是个好主意吗?几乎可以肯定不是。但截至 ES2015 年,它就在那里。
21赞 jakub.g 5/4/2019
2019 年访问者:查看这个几乎没有被点赞的答案,这是自 ES2017 以来最干净、最易读的最先进的技术:stackoverflow.com/a/37607084/245966Object.entries

答:

39赞 NickFitz 7/1/2009 #1

根据定义,JavaScript 对象是无序的(请参阅 ECMAScript 语言 规范,第 8.6 节)。语言规范甚至不能保证,如果连续两次迭代一个对象的属性,它们第二次会以相同的顺序出现。

如果需要对内容进行排序,请使用数组和 Array.prototype.sort 方法。

评论

4赞 Nosredna 7/1/2009
请注意,关于这一点有很多争论。大多数实现都按照添加元素的顺序保留列表。IIRC,Chrome 没有。关于Chrome是否应该与其他实现保持一致,存在争议。我的信念是 JavaScript 对象是一个哈希值,不应该假设任何顺序。我相信 Python 经历了同样的论点,并且最近引入了一个新的有序哈希列表。对于大多数浏览器,您可以通过重新创建对象、按排序值添加元素来做您想做的事。但你不应该。
0赞 Nosredna 7/1/2009
Chrome 通常会保持秩序,但并非总是如此。这是相关的 Chromium 错误: code.google.com/p/chromium/issues/detail?id=883
8赞 NickFitz 7/1/2009
该错误报告是不合理的,那些依赖未记录行为的人是那些有错误的人。阅读 ECMASCript 第 8.6 节;它明确指出“对象是无序的属性集合”。如果有人发现在一些实现中似乎不是这样,然后开始依赖特定于实现的行为,那就犯了一个大错误,他们不应该试图将责任从自己身上推卸。如果我是 Chrome 团队的一员,我会将该错误报告标记为“无效,WontFix”。
8赞 olliej 7/2/2009
EcmaScript 5 实际上将枚举的顺序定义为插入的顺序——在 ES3 中,没有定义被认为是一个规范错误。值得注意的是,EcmaScript 规范定义了没有人会认为合理的行为——例如,规范行为是在许多情况下在运行时抛出语法错误,根据规范错误地使用 continue、break、++、--, const 等任何在到达该代码之前抛出异常的引擎都是错误的
5赞 whitneyland 2/21/2012
@olliej - 我认为这是不正确的。该规范说:“没有指定枚举属性的机制和顺序(第一个算法中的步骤 6.a,第二个算法中的步骤 7.a)”。这是在最终草案的 PDF 的第 92 页。
1112赞 Nosredna 7/1/2009 #2

将它们移动到一个数组中,对该数组进行排序,然后将该数组用于您的目的。这里有一个解决方案:

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);

评论

26赞 Oleg V. Volkov 8/15/2012
您能否将“您可以重建”重新表述为“您可以使用数组来维护键的顺序并从对象中提取值”?正如您自己所提到的,它不仅是非标准的,而且这种错误的假设被当今不仅仅是Chrome以外的更多浏览器所打破,因此最好不要鼓励用户尝试它。
34赞 TheBrain 9/12/2012
下面是代码的更紧凑版本。Object.keys(maxSpeed).sort(function(a, b) {return -(maxSpeed[a] - maxSpeed[b])});
7赞 MrWhite 11/28/2012
@TheBrain:补充一点,只有IE9+(和其他现代浏览器)支持,如果这值得关注的话。还从元素原型链中排除可枚举属性(与 for..in) - 但这通常更可取。keys()keys()
31赞 dansch 2/20/2014
_.pairs将对象转换为 [ [key1, value1], [key2, value2] ]。然后调用排序。然后调用它将其转回。_.object
4赞 Chase Denecke 4/27/2021
是我疯了还是ES10解决方案不起作用?当我尝试它时,Object.fromEntries 创建了一个按键排序的对象,撤消了所有排序工作。
73赞 Stano 7/6/2012 #3

为了完整起见,此函数返回对象属性的排序数组

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()

评论

1赞 Will Hancock 8/17/2012
对象数组呢?[ {name:Will}, {name:Bill}, {name:Ben} ]
1赞 Stano 8/17/2012
嗨,威尔,您可以使用localeCompare函数进行此比较。将其添加到上面的答案中。
0赞 pfwd 11/14/2018
很棒的解决方案。字符串排序需要返回
0赞 Abrar Hossain 8/8/2019
@Stano 正确而简单的解决方案。非常感谢。
5赞 bonna 3/10/2013 #4

我正在遵循 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
}
509赞 Markus R 5/28/2013 #5

我们不想复制整个数据结构,也不想在需要关联数组的地方使用数组。

这是与 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

评论

34赞 Michael 1/7/2015
这似乎是按键而不是值排序,这不是问题所要求的?
42赞 Hanna 7/23/2015
它按值排序,并显示键 - 但是当它打印出来时,我们会丢失值计数,因为它只打印键。
8赞 Christopher Meyers 11/7/2015
在 JavaScript 中不能保证对象属性顺序,因此应该将排序到数组中,而不是对象中(这就是您所说的“关联数组”)。
9赞 Green 2/6/2017
别忘了。 是一个数组!不是对象!keysSorted
31赞 James Moran 1/10/2018
如果添加到排序的末尾,它将返回整个对象,而不仅仅是键.map(key => list[key]);
8赞 Roman Yudin 9/17/2013 #6

下划线.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>

253赞 inorganik 10/12/2013 #7

您的对象可以具有任意数量的属性,并且如果将对象放在数组中,则可以选择按所需的任何对象属性(数字或字符串)进行排序。考虑以下数组:

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);

http://jsfiddle.net/xsM5s/16/

评论

1赞 Lawrence Dol 3/13/2014
按名称排序不应剔除第一个字符;否则,并具有未定义的顺序。另外,您的排序实际上使用 ,而不是 .substrDianaDebrabyDatenumborn
0赞 Jemar Jones 3/22/2017
这看起来不错,但请注意,要比较字符串,您可以使用x.localeCompare(y)
2赞 inorganik 3/23/2017
@JemarJones看起来是一个非常有用的功能!请注意,并非所有浏览器都支持它 - IE 10 及以下版本、Safari Mobile 9 及以下版本。localCompare
0赞 Jemar Jones 3/24/2017
@inorganik 是的,对于那些需要支持这些浏览器的人来说,这是非常好的说明
1赞 João Pimentel Ferreira 4/16/2018
这是一个 Object 数组,它不是请求的 OP(具有多个属性的 Object)
3赞 Carson Wright 7/10/2014 #8

这可能是将其作为真实有序对象处理的简单方法。不知道它有多慢。使用 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)
1赞 Shimon Doodkin 10/18/2015 #9

许多类似且有用的功能: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;
}
146赞 kiding 6/3/2016 #10

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]]

评论

0赞 vsync 6/14/2017
这怎么可能回答问题的标题?我认为你误解了这个问题,因为你要改变原来的对象,而不是从中创建一个新的数组。Sorting JavaScript Object by property value
6赞 Darren Cook 4/4/2018
@vsync 此答案给出的结果与接受的答案相同,但代码较少且没有临时变量。
13赞 NetOperator Wibby 4/21/2018
FWIW,这个答案是干净的,是唯一帮助我的答案。
1赞 Vael Victus 12/9/2019
请注意,这不会保留密钥。
5赞 Avid 10/12/2021
为了进一步简化,将该过程合并为一行:let sorted = Object.entries(obj).sort((a, b) => a[1] - b[1]);
63赞 Jason J. Nathan 9/12/2016 #11

@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));

评论

2赞 Rohanil 1/5/2018
不适用于var myObj = {"1": {"Value": 40}, "2": {"Value": 10}, "3": {"Value": 30}, "4": {"Value": 20}};
9赞 Jason J. Nathan 1/6/2018
OP 的问题以及此答案不包含嵌套对象@Rohanil 也许你想问另一个问题,而不是投反对票。具有各种类型的嵌套对象显然需要比此解决方案提供的更多
0赞 ZorgoZ 10/25/2018
请注意:您的更新实际上不起作用。至少不是到处都是,也不是因为.根据该标准,对象是属性的无序集合。好吧,这意味着如果您尝试在按属性值或其他任何内容对新对象进行排序后构造新对象,则属性键排序将再次变得未定义。例如,Chrome 默认对属性键进行排序,因此每次尝试以不同的方式对它们进行排序都是无用的。你唯一的机会是根据你的排序偏好获得一个“索引”,并相应地遍历原始对象。entries
0赞 Jason J. Nathan 10/29/2018
是的,@ZorgoZ,你是对的,很多人在这篇文章中都提到了它。大多数情况下,我们在转换为另一种类型(如 JSON)或另一个 reduce 函数之前使用此函数作为转换。如果目标是此后改变对象,则可能会出现意外结果。我已经成功地跨引擎使用此功能。
0赞 png 2/5/2019
注意:您不想在sort()Object.entries()
12赞 julianljk 12/9/2016 #12

使用 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

评论

0赞 T.J. Crowder 1/1/2017
同样在 ES6 (ES2015) 中:对象属性确实有顺序(或者有一种方法可以按照定义顺序访问它们,具体取决于您的观点)。如果属性名称是字符串,并且看起来不像数组索引,则顺序是它们添加到对象的顺序。此顺序指定为 或 遵守,但定义为 和 用于访问属性名称数组的其他新方法遵守。所以这是另一种选择。for-inObject.keysObject.getOwnPropertyNames
0赞 Green 2/6/2017
但是“排序”操作在哪里?它们根本没有排序
0赞 julianljk 2/8/2017
@Green 我想我想在这里强调的是,你实际上有一个数据结构,可以按排序顺序存储(对数据进行排序,遍历它并将其存储在地图中),因为你不能保证对象。Map
10赞 Vasil Nikolov 2/14/2017 #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}

评论

0赞 Ajay Singh 4/27/2017
简单而完美!这回答了这个问题。谢谢。
0赞 ParoX 5/30/2017
在 javascript 中不能保证键顺序,所以如果键是整数等,这对我来说是失败的
0赞 kakadais 1/29/2018
确切地说,ParoX。当键为整数类型时,这无法正常工作。
37赞 Alireza 8/2/2017 #14

好的,您可能知道,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}

同样这样,主对象不会被触及,我们实际上会得到一个新对象。

我还创建了下面的图像,以使功能步骤更加清晰,以防您需要对其进行一些更改以按照自己的方式工作:

Sorting a javascript object by property value

评论

8赞 ROROROOROROR 8/28/2017
这是按键排序,而不是按值排序。
0赞 Alireza 8/28/2017
@ROROROOROROR,这只是一个指示它的工作原理,因为它们没有那么不同,但都很好,我也会添加按值排序
1赞 VtoCorleone 11/2/2017
按值排序是错误的,它是您的数据集。改成,你会看到它分崩离析。c: 3c: 13
2赞 Michael Ryan Soileau 4/23/2018
@VtoCorleone 这只是一个自然的排序错误,1 排在第一位,而不是所呈现的算法中的缺陷。
1赞 respectabiggle 8/27/2023
这正是我要找的,谢谢
2赞 victorhazbun 4/6/2018 #15

按值排序的对象 (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;
}
2赞 Milad Aslani 9/3/2018 #16
    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 }
2赞 Kiran Debnath 9/6/2018 #17
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 } ]

3赞 esneyderp 10/29/2018 #18

以防万一,有人正在寻找保留对象(带有键和值),使用 @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}

评论

2赞 DiegoRBaquero 3/9/2019
你正在返回一个作业,会更好mapforEach
9赞 daniil4udo 5/16/2019 #19

在没有多个 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) 

9赞 Maryam Koulaei 8/23/2019 #20

非常简短和简单!

var sortedList = {};
Object.keys(list).sort((a,b) => list[a]-list[b]).forEach((key) => {
    sortedList[key] = list[key]; });
3赞 orad 9/26/2019 #21

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 });

评论

0赞 Sudipta Dhara 8/4/2020
我可以用javascript吗?
0赞 VenkateshMogili 10/17/2020
非常感谢,这个解决方案对我有用。我在没有字典接口的 Javascript 中使用了同样的东西。const Countries = { “AD”: { “name”: “Andorra”, }, “AE”: { “name”: “阿拉伯联合酋长国”, }, “IN”: { “name”: “India”, }, } // 对对象内的对象进行排序。var sortedMap = sort(国家, val => val.name);转换为对象。var sortedObj = {};sortedMap.forEach((v,k) => { sortedObj[k] = v });控制台.log(sortedObj);输出: {“AD”: {“name”: “安道尔”},“IN”: {“name”: “印度”},“AE”: {“name”: “阿拉伯联合酋长国”}}
0赞 Amr 10/19/2023
这是方式 - 应该是公认的答案
2赞 Oleg 1/12/2020 #22
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;
    });
4赞 Remi Prasanna 2/12/2020 #23
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 ] ]
2赞 Ivan Bozveliev 3/3/2020 #24

我的解决方案与排序:

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]);
}
3赞 Chirag Modi 5/14/2020 #25
<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>

评论

2赞 jtate 5/14/2020
欢迎来到 stackoverflow。除了您提供的答案外,请考虑简要说明这解决问题的原因和方式。
4赞 Jasp402 7/9/2020 #26

有很多方法可以做到这一点,但由于我没有看到任何用途,所以我把它放在这里。也许它对某人来说似乎是有用的。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);

4赞 VenkateshMogili 10/17/2020 #27

感谢 @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"}}

4赞 Henke 3/19/2021 #28

按值对对象属性进行排序

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}

引用:

2赞 simon 11/23/2021 #29

一个早已过时的问题的后续答案。我编写了两个函数,一个按键排序,另一个按值排序,并在两个函数中以排序形式返回对象。它也应该适用于字符串,因为这就是我发布此内容的原因(如果值不是数字,则在按值排序时遇到上述一些困难)。

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))

3赞 Ali Zain UL Yasoob 3/30/2023 #30

这是实现此目的的另一种方法

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);