最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

sorting - Sort a JavaScript object by key or value; ES6 - Stack Overflow

programmeradmin1浏览0评论

Before I ask; there are a bunch of discussions on this particular subject, most of which pertain to ES5 and do not necessarily hold truth for ES6. I'm attempting to get some clarification, and maybe help the next person that is scouring the internet for an answer. This is in reference to ES6 specifically.

QUESTIONS:

Consider the following object structure:

const unsorted_object = {
    'C': '0003',
    'D': '0004',
    'A': '0001',
    'B': '0002',
    'F': '0005',
}; 
  1. How can I sort a JavaScript object by key? (Answered here)

    const sorted_object = {};
    Object.keys(unsorted_object).sort().forEach(function(key) {
        sorted_object[key] = unsorted_object[key];
    });
    
  2. How can I sort a JavaScript object by the key value?

EDIT #1

I might not have been totally clear on question #2. The idea is to sort the JavaScript object by the value of the key, not by key and value.

EDIT #2

const unsorted_object = {
    '0001': '13.1666',
    '0002': '11.0001',
    '0003': '10.6664',
    '0004': '13.1666',
    '0005': '7.3331',
};

Output:

'0001': '13.1666'
'0004': '13.1666'
'0002': '11.0001'
'0003': '10.6664'
'0005': '7.3331'

Before I ask; there are a bunch of discussions on this particular subject, most of which pertain to ES5 and do not necessarily hold truth for ES6. I'm attempting to get some clarification, and maybe help the next person that is scouring the internet for an answer. This is in reference to ES6 specifically.

QUESTIONS:

Consider the following object structure:

const unsorted_object = {
    'C': '0003',
    'D': '0004',
    'A': '0001',
    'B': '0002',
    'F': '0005',
}; 
  1. How can I sort a JavaScript object by key? (Answered here)

    const sorted_object = {};
    Object.keys(unsorted_object).sort().forEach(function(key) {
        sorted_object[key] = unsorted_object[key];
    });
    
  2. How can I sort a JavaScript object by the key value?

EDIT #1

I might not have been totally clear on question #2. The idea is to sort the JavaScript object by the value of the key, not by key and value.

EDIT #2

const unsorted_object = {
    '0001': '13.1666',
    '0002': '11.0001',
    '0003': '10.6664',
    '0004': '13.1666',
    '0005': '7.3331',
};

Output:

'0001': '13.1666'
'0004': '13.1666'
'0002': '11.0001'
'0003': '10.6664'
'0005': '7.3331'
Share Improve this question edited Jun 20, 2020 at 9:12 CommunityBot 11 silver badge asked Mar 23, 2019 at 22:46 artomasonartomason 4,0036 gold badges27 silver badges45 bronze badges 12
  • Why do you want to sort an Object (they are unordered by design)? Can you explain the bigger picture of what you want to do? – JBallin Commented Mar 23, 2019 at 22:51
  • @JBallin In ES6+, object properties are ordered - it's only in ES5 and before that they have no defined order. – CertainPerformance Commented Mar 23, 2019 at 22:51
  • Possible duplicate of Sorting JavaScript Object by property value – JBallin Commented Mar 23, 2019 at 22:55
  • @JBallin I disagree. I feel that the question, asked in 2010, was answered under the premise of ES5 and thus is not ES6 specific. – artomason Commented Mar 23, 2019 at 22:59
  • @artomason some answers use ES6. If you truly think it's different, you should edit your title to be ES6 specific. – JBallin Commented Mar 23, 2019 at 23:01
 |  Show 7 more comments

4 Answers 4

Reset to default 9

Objects keys in ES6 have a traversal order. Integer keys are always first, and are sorted in an ascending order (0 -> 9). In non integer keys the order of assignment is preserved (see this article). To sort the object's keys we need to recreate the object, and add the keys in the required order.

Note: This means that sorting will only work on non integer keys, because integers are always 1st, and always sorted in an ascending order.

To sort and recreate the object:

  • Use Object.entries() to get an array of key/value pairs - [[key, value], [key, value]]
  • Sort them by the value (the 2nd item in the pair) using array destructuring - [, v1]. Cast the strings to number using the + operator,
  • Reduce back to an object. Take the key and value using destructuring [k , v], and add them to the accumulator object using computed property names - ({ [k]: v }), and object spread - ({ ...r, [k]: v })

const unsorted_object = {
    '0001': '13.1666',
    '0002': '11.0001',
    '0003': '10.6664',
    '0004': '13.1666',
    '0005': '7.3331',
};

const sorted_object = Object.entries(unsorted_object)
  .sort(([,v1], [,v2]) => +v2 - +v1)
  .reduce((r, [k, v]) => ({ ...r, [k]: v }), {});

console.log(sorted_object);

If supported you can create the object from the entries using Object.fromEntries() instead of Array.reduce():

const unsorted_object = {
    '0001': '13.1666',
    '0002': '11.0001',
    '0003': '10.6664',
    '0004': '13.1666',
    '0005': '7.3331',
};

const sorted_object = Object.fromEntries(
  Object.entries(unsorted_object)
    .sort(([,v1], [,v2]) => +v2 - +v1)
);

console.log(sorted_object);

Edge friendly version, that uses Object.assign() instead of spread:

const unsorted_object = {
    '0001': '13.1666',
    '0002': '11.0001',
    '0003': '10.6664',
    '0004': '13.1666',
    '0005': '7.3331',
};

const sorted_object = Object.entries(unsorted_object)
  .sort(([,v1], [,v2]) => +v2 - +v1)
  .reduce((r, [k, v]) => Object.assign(r, { [k]: v }), {});

console.log(sorted_object);

Extract the entries instead of the keys, then sort by the difference of each value:

const unsorted_object = {
    'C': '0003',
    'D': '0004',
    'A': '0001',
    'B': '0002',
    'F': '0005',
};

const sorted_object = {};
Object.entries(unsorted_object)
  .sort((a, b) => a[1] - b[1])
  .forEach(([key, val]) => {
    sorted_object[key] = val;
  });
console.log(sorted_object);

Note that it's probably more appropriate to use reduce to construct an object from an array:

const unsorted_object = {
    'C': '0003',
    'D': '0004',
    'A': '0001',
    'B': '0002',
    'F': '0005',
};

const sorted_object = Object.entries(unsorted_object)
  .sort((a, b) => a[1] - b[1])
  .reduce((a, [key, val]) => {
    a[key] = val;
    return a;
  }, {});
console.log(sorted_object);

You can sort entries and use a reduce() to create new object.

With that said there is likely something wrong in your app design for needing to even do such an operation

const unsorted_object = {
  'C': '0003',
  'D': '0004',
  'A': '0001',
  'B': '0002',
  'F': '0005',
};

const sorted = Object.entries(unsorted_object)
  .sort((a, b) => a[1] - b[1])
  .reduce((a, c) => (a[c[0]] = c[1], a), {})

console.log(sorted)

A cleaner way is to do

Object.entries(unsorted_object)
  .sort()
  .reduce((acc, [k, v]) => ({ ...acc, [k]: v }), {});

This builds up an empty object based on the sorted tuples

发布评论

评论列表(0)

  1. 暂无评论