70

Here is my dictionary:

const dict = { "x" : 1, "y" : 6, "z" : 9, "a" : 5, "b" : 7, "c" : 11, "d" : 17, "t" : 3 }; 

I need a way to sort my dict dictionary from the least to the greatest or from the greatest to the least. Or even it would be fine I had an array with the sorted keys in it. But I do not know how to do such thing using javascript. I have done it before using python, like this:

import heapq from operator import itemgetter thirty_largest = heapq.nlargest(8, dict.iteritems(), key=itemgetter(1)) 

I have searched for it in Google and I found that arrays have sort() function but not dictionaries. So my question is: How can I sort the dictionary or get top 5 biggest values in sort order?

6
  • 2
    In JS, you have objects (not dictionaries). There is some questions on SO about this subject... You can have a look to for example : Sorting JavaScript Object by property value. Commented Aug 26, 2014 at 7:30
  • 1
    It rather seems to be by values, see the last line : get top 5 biggest values... Commented Aug 26, 2014 at 7:37
  • 1
    Since objects (dictionaries) in javascript has no order, sorting such a thing makes no sense. As such I'd strongly suggest you change the title to "How do I get the top 5 biggest values" to avoid people closing this question. Commented Aug 26, 2014 at 7:39
  • 3
    He said that he wanted to sort a dictionary by its keys. Dictionaries don't exist in JS, so we may build a key/value ordered structure to suit his needs, which can look like a 'dictionary'. No need to change his question. I think this is a common problem for people coming from other languages, so in my opinion this title should be kept as it is Commented Aug 26, 2014 at 8:22
  • 2
    Object.keys(dict).sort() returns an array with the keys sorted. You can then use it to loop over the dictionary when you need it. Commented Aug 26, 2014 at 8:30

9 Answers 9

115

It may not be straight forward in JavaScript.

var dict = { "x": 1, "y": 6, "z": 9, "a": 5, "b": 7, "c": 11, "d": 17, "t": 3 }; // Create items array var items = Object.keys(dict).map(function(key) { return [key, dict[key]]; }); // Sort the array based on the second element items.sort(function(first, second) { return second[1] - first[1]; }); // Create a new array with only the first 5 items console.log(items.slice(0, 5));

The first step, creating items array, is similar to Python's

items = map(lambda x: [x, var[x]], var.keys()) 

which can be conveniently written as

items = list(dict.items()) 

and the sorting step is similar to Python's sorting with cmp parameter

items.sort(cmp=lambda x, y: y[1] - x[1]) 

and the last step is similar to the Python's slicing operation.

print items[:5] // [['d', 17], ['c', 11], ['z', 9], ['b', 7], ['y', 6]] 
Sign up to request clarification or add additional context in comments.

2 Comments

Showing the versions in python was confusing to me. I wish you had only shown the javascript.
Thanks for showing the Python equivalent.
12

The answer provided by @thefourtheye works to an extent, but it does not return the same "dictionary" structure.

If you want to return a sorted object with the same structure you started with, you can run this on the items returned from the accepted answer:

sorted_obj={} $.each(items, function(k, v) { use_key = v[0] use_value = v[1] sorted_obj[use_key] = use_value }) 

Combine them for a single function that sorts a JavaScript object:

function sort_object(obj) { items = Object.keys(obj).map(function(key) { return [key, obj[key]]; }); items.sort(function(first, second) { return second[1] - first[1]; }); sorted_obj={} $.each(items, function(k, v) { use_key = v[0] use_value = v[1] sorted_obj[use_key] = use_value }) return(sorted_obj) } 

Example:

Simply pass your object into the sort_object function:

dict = { "x" : 1, "y" : 6, "z" : 9, "a" : 5, "b" : 7, "c" : 11, "d" : 17, "t" : 3 }; sort_object(dict) 

Result:

{ "d":17, "c":11, "z":9, "b":7, "y":6, "a":5, "t":3, "x":1 } 

"Proof":

res = sort_object(dict) $.each(res, function(elem, index) { alert(elem) }) 

3 Comments

but... isn't looping through a dictionary, by definition, unordered? I mean, if I print out that dictionary it's going to be in random order
@johnktejik see the "proof" in answer...it will reproducibly loop with the new order. Technically you're correct, order shouldn't be trusted in "dictionary" type objects in JavaScript, but if you're utilizing the newly ordered object immediately after invoking sort_object you can use it. So technically Rayjax is correct, use arrays of objects since this guarantees order, but there could be use cases for quickly ordering your object on the fly as I've shown.
good job, btw, use items.forEach( function(v) { ... }) instead of $.each(items, function(k, v) { ... }) for better compatibility in different version of JS engines
7

First things first, what you may call a 'dictionary' is called an 'Object' in JavaScript. Your 'dict' variable is an object.

Objects are not ordered in JS, so you cannot sort an object. Fortunately arrays are ordered; we will convert your dictionary to an array. Just take a look below.

//dict -> a js object var dict = {"x" : 1, "y" : 6, "z" : 9, "a" : 5, "b" : 7, "c" : 11, "d" : 17, "t" : 3}; //Use the 'keys' function from the Object class to get the keys of your dictionary //'keys' will be an array containing ["x", "y", "z"...] var keys = Object.keys(dict); //Get the number of keys - easy using the array 'length' property var i, len = keys.length; //Sort the keys. We can use the sort() method because 'keys' is an array keys.sort(); //This array will hold your key/value pairs in an ordered way //it will be an array of objects var sortedDict = []; //Now let's go throught your keys in the sorted order for (i = 0; i < len; i++) { //get the current key k = keys[i]; //show you the key and the value (retrieved by accessing dict with current key) alert(k + ':' + dict[k]); //Using the array 'push' method, we add an object at the end of the result array //It will hold the key/value pair sortedDict.push({'key': k, 'value':dict[k]}); } //Result console.log(sortedDict); 

You can try it here

If you want to change the sorting, have a look here

If you want the first five biggest values, well, loop over sortedDict with a for loop 5 times and get those values out:

function getFiveFirstValues(){ var valuesArray = []; for (i = 0; i < 5; i++) { valuesArray.push(sortedDict[i].value); } return valuesArray; } 

Please remember that in JavaScript, objects are UNORDERED. They may seem to be ordered, but they are not, and depending on the JS implementation of your browser their order can be different.

In this example, sortedDict is an Array (which is ordered) and thus can be sorted. In each element of that array, you will find a KEY and VALUE pair for each pair of your 'dictionary'.

Comments

5

You can try the following code. It gets sorted integer array by value.

jsFiddle link

 function sortJsObject() { var dict = {"x" : 1, "y" : 6, "z" : 9, "a" : 5, "b" : 7, "c" : 11, "d" : 17, "t" : 3}; var keys = []; for(var key in dict) { keys[keys.length] = key; } var values = []; for(var i = 0; i < keys.length; i++) { values[values.length] = dict[keys [i]]; } var sortedValues = values.sort(sortNumber); console.log(sortedValues); } // this is needed to sort values as integers function sortNumber(a,b) { return a - b; } 

Hope it helps.

2 Comments

how to get the dictionary back with this sorted value?
@SaurabhSashank just return it? like return sortedValues ?
2

Strictly speaking, you cannot sort a "dictionary" (JavaScript object), because JavaScript objects have no order. They are merely a "bag" of key/value pairs.

If you want to find the n largest values in the object, then one way or another you need to convert the object into an array, whose elements are ordered, such as with @thefourtheye's solution. If you want to sort the keys, then well, sort them with Object.keys(object).sort() as another answer shows you how to.

Comments

2

This is a complete piece of code, according to previous answers and How to iterate (keys, values) in JavaScript?:

class DictUtils { static entries(dictionary) { try { //ECMAScript 2017 and higher, better performance if support return Object.entries(dictionary); } catch (error) { //ECMAScript 5 and higher, full compatible but lower performance return Object.keys(dictionary).map(function(key) { return [key, dictionary[key]]; }); } } static sort(dictionary, sort_function) { return DictUtils.entries(dictionary) .sort(sort_function) .reduce((sorted, kv)=>{ sorted[kv[0]] = kv[1]; return sorted; }, {}); } } class SortFunctions { static compare(o0, o1) { //TODO compelte for not-number values return o0 - o1; } static byValueDescending(kv0, kv1) { return SortFunctions.compare(kv1[1], kv0[1]); } static byValueAscending(kv0, kv1) { return SortFunctions.compare(kv0[1], kv1[1]); } } let dict = { "jack": 10, "joe": 20, "nick": 8, "sare": 12 } let sorted = DictUtils.sort(dict, SortFunctions.byValueDescending) console.log(sorted);

Comments

2

This function takes in a dict, or more commonly called object in JavaScript, and returns a list sorted by the object's values.

function sortObj(obj) { // Sort object as list based on values return Object.keys(obj).map(k => ([k, obj[k]])).sort((a, b) => (b[1] - a[1])) } 

It does the same as the answer by @thefourtheye, but it is much more terse.

Comments

1

Just jumping in with another response:

const k = 5; const dict = { "x" : 1, "y" : 6, "z" : 9, "a" : 5, "b" : 7, "c" : 11, "d" : 17, "t" : 3 }; const compare = (a, b) => { if(a > b) return -1; if(a < b) return 1; return 0 }; // Object.entries() to convert the dict to: [["x",3],["y",1],["z",2]] let arr = Object.entries(dict).sort((a, b) => compare(a[1], b[1])); // Getting the first k = 5 biggest elements: let biggestElemsArr = []; for(let j = 0; j < k; j++) { biggestElemsArr.push(arr[j][0]); } console.log(biggestElemsArr); 

Comments

0
const sortObjectByValues = (dict: { [key: string]: number }, direction: 'asc'| 'desc' = 'asc') => { return Object.fromEntries(Object.entries(dict).sort((a, b) => { if (direction === 'asc') { return a[1] - b[1] } return b[1] - a[1] })) } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.