Сортировка словаря по значению в JavaScript

Вот мой словарь:

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

Мне нужен способ отсортировать словарь dict от наименьшего до максимального или от максимального до наименьшего. Или даже было бы хорошо, у меня был массив с отсортированными клавишами в нем. Но я не знаю, как это сделать, используя javascript. Я сделал это перед использованием python, например:

import heapq
from operator import itemgetter

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

Я искал его в Google, и я обнаружил, что у массивов есть функция sort(), но не словари. Поэтому мой вопрос: Как я могу отсортировать словарь или получить 5 самых больших значений в порядке сортировки?

Ответ 1

Это может быть не так просто в 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));

Ответ 2

Вы можете попробовать следующий код. Он сортирует целочисленный массив по значению.

jsFiddle ссылка

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

Надеюсь, что это поможет.

Ответ 3

Прежде всего, то, что вы можете назвать "словарем", называется "Object" в JavaScript. Ваша переменная 'dict' является объектом.

Объекты не упорядочены в JS, поэтому вы не можете сортировать объект. К счастью, массивы упорядочены; мы преобразуем ваш словарь в массив. Просто взгляните ниже.

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

Вы можете попробовать здесь

Если вы хотите изменить сортировку, посмотрите здесь

Если вам нужны первые пять самых больших значений, ну, зациклируйте на sortedDict с циклом for 5 раз и получите эти значения:

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

Помните, что в JavaScript объекты UNORDERED. Они могут показаться упорядоченными, но их нет, и в зависимости от реализации JS вашего браузера их порядок может быть другим.

В этом примере sortedDict представляет собой массив (который упорядочен) и поэтому может быть отсортирован. В каждом элементе этого массива вы найдете пару KEY и VALUE для каждой пары вашего словаря.

Ответ 4

Строго говоря, вы не можете сортировать "словарь" (объект JavaScript), потому что объекты JavaScript не имеют порядка. Они всего лишь "мешок" пар ключ/значение.

Если вы хотите найти n наибольших значений в объекте, то так или иначе вам нужно преобразовать объект в массив, элементы которого упорядочены, например, с решением @thefourtheye. Если вы хотите отсортировать ключи, то хорошо, отсортируйте их с помощью Object.keys(object).sort(), поскольку еще один ответ показывает, как это сделать.

Ответ 5

Ответ, предоставленный @thefourtheye, работает до некоторой степени, но он не возвращает ту же структуру "словаря".

Если вы хотите вернуть отсортированный объект с той же структурой, с которой вы начали, вы можете выполнить это для элементов, возвращенных из принятого ответа:

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

Объедините их для одной функции, которая сортирует объект JavaScript:

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

Пример:

Просто передайте ваш объект в функцию sort_object:

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

sort_object(dict)

Результат:

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

"Доказательство":

res = sort_object(dict)

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