Nano Hash - криптовалюты, майнинг, программирование

Сортировка свойств объекта по значениям

Если у меня есть объект JavaScript, например:

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

Есть ли способ отсортировать свойства по значению? Так что я в итоге

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

  • Не только сортировка, но, что более важно, сортировка чисел. Числа невосприимчивы к методу Javascripts Array.sort (), что означает, что вам не просто нужно будет найти метод для сортировки свойств, но вам придется написать свою собственную функцию для сравнения числовых значений. 01.07.2009
  • AFAIK, объекты не имеют никакого порядка, как массивы. 07.10.2016
  • Прежде чем вы прочитаете ответы: Ответ - Нет. Порядок свойств объекта в ECMAScript нестандартный. Никогда не следует делать предположений о порядке элементов в объекте JavaScript. Объект - это неупорядоченный набор свойств. В приведенных ниже ответах показано, как использовать отсортированные свойства с помощью массивов, но при этом никогда не изменять порядок свойств самих объектов. Итак, нет, это невозможно. Даже если вы создаете объект с предварительно отсортированными свойствами, не гарантируется, что они будут отображаться в том же порядке в будущем. Читать дальше :). 29.10.2016
  • @GovindRai тем не менее, в реальных интерфейсных приложениях мы перебираем коллекции объектов с идентификаторами в качестве ключей, и порядок важен при переводе в шаблоны HTML. Вы говорите, что у них нет порядка, я говорю, что они имеют именно тот порядок, который я вижу, когда console.logging их в текущем браузере. И этот заказ можно изменить. Как только вы их перебираете, у них есть порядок. 19.12.2016
  • @GovindRai: Теперь есть средства доступа к свойствам в указанном в спецификации порядке. Это хорошая идея? Почти наверняка нет. :-) Но он есть, по состоянию на ES2015. 31.12.2016
  • @ T.J. Crowder, ты абсолютно прав. Тем не менее, несмотря на все предостережения, связанные с этим дополнением, я надеюсь, что наши коллеги из SO'ов прочитают границу перед принятием этого нового подхода (как всегда и должно быть). : D 31.12.2016
  • Посетители 2019 г .: проверьте этот ответ на основе Object.entries, который едва набрал наибольшее количество голосов, который является самым чистым и читаемым со времен ES2017: stackoverflow.com/a / 37607084/245966 04.05.2019
  • @ jakub.g прав. Ответ так же прост, как Object.entries(list).sort((a, b) => a[1] - b[1]). Он создает упорядоченный массив с парами ключ / значение, но, вероятно, удовлетворяет многим требованиям. 15.01.2020
  • Зачем тебе это делать? 11.03.2020
  • Chrome (83) сортирует свойства по имени, когда вы используете console.log, поэтому может возникнуть путаница, если вы полагаетесь на это, чтобы проверить, работает ли ваша сортировка. 13.07.2020

Ответы:


1

Переместите их в массив, отсортируйте этот массив и затем используйте этот массив для своих целей. Вот решение:

var maxSpeed = {
    car: 300, 
    bike: 60, 
    motorbike: 200, 
    airplane: 1000,
    helicopter: 400, 
    rocket: 8 * 60 * 60
};
var 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.

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

01.07.2009
  • Не могли бы вы переформулировать, что вы можете перестроить, чтобы вы могли использовать массив для поддержания порядка ключей и извлечения значений из объекта? Мало того, что это нестандартно, как вы сами отметили, это ошибочное предположение нарушает большее количество браузеров, чем только Chrome, поэтому лучше не поощрять пользователей пробовать его. 15.08.2012
  • Вот более компактная версия вашего кода. Object.keys (maxSpeed) .sort (function (a, b) {return - (maxSpeed ​​[a] - maxSpeed ​​[b])}); 12.09.2012
  • @TheBrain: Чтобы добавить, keys() поддерживается только IE9 + (и другими современными браузерами), если это вызывает беспокойство. Также keys() исключает перечислимые свойства из цепочки прототипов элементов (в отличие от for..in) - но это обычно более желательно. 28.11.2012
  • Почему бы не использовать сортировку вставкой? Должно быть быстрее, чем преобразование обратно в массив, если сортировка вставкой используется любыми способами (в Chrome для массивов с менее чем 10 элементами), а затем обратно к объекту. Мне кажется, что это не реализовано в цепочке прототипов для объектов. 09.11.2013
  • _.pairs превращает объект в [[ключ1, значение1], [ключ2, значение2]]. Затем вызовите сортировку по этому поводу. Затем вызовите _.object, чтобы вернуть его обратно. 20.02.2014
  • Очень хороший пример! Спасибо. Если вам нужен порядок DESC - ›замените оператор return на: return b [1] - a [1] 30.10.2016
  • Во-первых, ссылки больше не существует. Во-вторых, я думаю, что если объект очень большой, не будет ли слишком дорого скопировать все в массив, выполнить операцию сортировки и вернуться к объекту? 05.03.2017
  • Если вы сортируете string keys, вы можете использовать: return a[1] > b[1];. 20.07.2018
  • Почему мне нужно искать в Google, чтобы вернуться к этому раз в неделю 02.10.2018
  • Мой проект требует объектных ключей для чистого слияния, но также требует явной сортировки, поскольку метаданные управляют пользовательским интерфейсом. Я последовал аналогичному подходу, только добавил проверку hasOwnProperty, чтобы не ползать вверх по цепочке прототипов. Вот хорошая статья об итерации свойств объекта в JS hackernoon.com/ 02.03.2019
  • @ OlegV.Volkov имеет ввиду это var sortedAsObject = {}; sortable.forEach(function(item){sortedAsObject[item[0]]=item[1]}) 10.09.2019
  • В приведенном выше примере Object.fromEntries(Object.entries(maxSpeed).sort((a,b) => a[1]-b[1])); работает? 16.09.2020
  • Пример ES8 не работает, и понятия не имею, как исправить. 21.12.2020
  • Я сумасшедший или решение ES10 не работает? Когда я пробую его, Object.fromEntries создает объект, отсортированный по ключу, отменяя всю работу по сортировке. 27.04.2021

  • 2

    Мы не хотим дублировать всю структуру данных или использовать массив там, где нам нужен ассоциативный массив.

    Вот еще один способ сделать то же самое, что и 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

    28.05.2013
  • Кажется, это сортировка по ключу, а не по значению, а вопрос не к чему? 07.01.2015
  • @Michael keysSorted содержит ключи (вы, я и т. Д.) В последних версиях Safari, Chrome и Firefox на момент написания этой статьи, и они отсортированы по значению. 11.05.2015
  • Он сортируется по значению и отображает ключи - но мы теряем счетчик значений, когда он распечатывает, поскольку он печатает только ключи. 23.07.2015
  • Порядок свойств объекта не гарантируется в JavaScript, поэтому сортировку следует производить по массиву, а не по объекту (который вы называете «ассоциативным массивом»). 06.11.2015
  • @ChristopherMeyers высказывает очень веское мнение! Я использовал это, но получил неожиданные результаты. 02.03.2016
  • @ChristopherMeyers Сортировка выполняется в массиве. Он получается из Object.keys (), затем сортируется путем сравнения значений в исходном объекте. 19.07.2016
  • @Johannes Если вы хотите распечатать значения, вам нужно перебрать отсортированные ключи и распечатать значения из исходной структуры данных - что мы не потеряли. 19.07.2016
  • @MarkusR Так оно и есть. Так что, это. Не уверен, в чем была моя проблема. Хороший ответ! 19.07.2016
  • @Michael Сортировка по значению. Мы говорим sort () сравнивать значения в этой части: function (a, b) {return list [a] -list [b]} 19.07.2016
  • Не забывай. keysSorted - это массив! Не объект! 06.02.2017
  • Если вы добавите .map(key => list[key]); в конец сортировки, он вернет весь объект, а не только ключ 10.01.2018
  • @JamesMoran добавляет, что возвращает значение только для этого ключа, а не для всего объекта. 21.04.2021

  • 3

    У ваших объектов может быть любое количество свойств, и вы можете выбрать сортировку по любому свойству объекта, которое вы хотите, номеру или строке, если вы поместите объекты в массив. Рассмотрим этот массив:

    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/

    11.10.2013
  • Сортировка по имени не должна substr выходить за пределы первого символа; иначе Diana и Debra имеют неопределенный порядок. Кроме того, ваша сортировка byDate фактически использует num, а не born. 12.03.2014
  • Выглядит неплохо, но учтите, что для сравнения строк можно просто использовать x.localeCompare(y) 22.03.2017
  • @JemarJones localCompare выглядит очень полезной функцией! Обратите внимание, что он будет поддерживаться не всеми браузерами - IE 10 и менее, Safari Mobile 9 и менее. 22.03.2017
  • @inorganik Да, очень хорошее примечание для тех, кому нужна поддержка этих браузеров. 23.03.2017
  • Это массив объектов, который не является запрашиваемым OP (объект с несколькими свойствами) 15.04.2018
  • Это то, что я искал. Сортировка объекта javascript с одним из свойств. 21.01.2019

  • 4

    ECMAScript 2017 представляет Object.values / Object.entries. Как следует из названия, первая объединяет все значения объекта в массив, а вторая - весь объект в массив [key, value] массивов; Эквивалент dict.values() и _ 4_.

    Эти функции значительно упрощают сортировку любого хэша в упорядоченный объект. На данный момент только небольшая часть платформ 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]]
    
    03.06.2016
  • как это возможно отвечает на заголовок вопроса Sorting JavaScript Object by property value? Вы неправильно поняли вопрос, я думаю, поскольку вы должны изменить исходный объект, а не создавать из него новый массив. 14.06.2017
  • @vsync Этот ответ дает тот же результат, что и принятый ответ, но с меньшим количеством кода и без временной переменной. 03.04.2018
  • FWIW, этот ответ чистый и единственный, который мне помог. 21.04.2018
  • только в ff, а не ie, и chrome больше не сортируют объекты автоматически. wtf 27.06.2019
  • Просто обратите внимание, что это не сохранит ключи. 08.12.2019
  • И работает в 2020 (почти 2021) !!!! 21.12.2020

  • 5

    Для полноты картины эта функция возвращает отсортированный массив свойств объекта:

    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) { 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 () для сравнения строк с учетом регистра .

    05.07.2012
  • А как насчет массива объектов? [{name: Will}, {name: Bill}, {name: Ben}] 16.08.2012
  • Привет, Уилл, вы можете использовать функцию localeCompare для этого сравнения. Добавил его к ответу выше. 16.08.2012
  • Отличное решение. Сортировка строк требует возврата 14.11.2018
  • @Stano Правильное и простое решение. Огромное спасибо. 08.08.2019

  • 6

    Версия ответа от @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
    

    UPDATE: April 2017 This returns a sorted myObj object defined above.

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

    UPDATE: March 2021 - Object.entries with sort function (updated as per comments)

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

    12.09.2016
  • не работает для var myObj = {"1": {"Value": 40}, "2": {"Value": 10}, "3": {"Value": 30}, "4": {"Value": 20}}; 05.01.2018
  • Вопрос OP вместе с этим ответом не содержит вложенных объектов @Rohanil Может быть, вы захотите задать другой вопрос вместо отрицательного голосования. Ваш вложенный объект с различными типами, очевидно, требует большего, чем предоставляет это решение. 06.01.2018
  • Просто примечание: ваши обновления на самом деле не будут работать. По крайней мере, не везде и не из-за entries. Согласно стандарту объект представляет собой неупорядоченный набор свойств. Что ж, это означает, что если вы пытаетесь создать новый объект после его сортировки по значению свойства или чему-либо еще, порядок ключей свойств снова становится неопределенным. Например, Chrome по умолчанию упорядочивает ключи свойств, поэтому каждая попытка упорядочить их по-другому бесполезна. Ваш единственный шанс - получить индекс, основанный на ваших предпочтениях упорядочивания, и соответствующим образом пройти по исходному объекту. 25.10.2018
  • Да, @ZorgoZ, вы правы, и многие люди упоминали об этом в этом посте. В большинстве случаев мы используем эту функцию как преобразование перед преобразованием в другой тип (например, JSON) или перед другой функцией сокращения. Если после этого нужно изменить объект, это может привести к неожиданным результатам. Я добился успеха с этой функцией во всех двигателях. 29.10.2018
  • Примечание: вы не хотите использовать sort() на Object.entries() 05.02.2019
  • Object.assign() будет намного эффективнее, чем распространение _sortedObj в сокращении 08.03.2019
  • Не уверен, что это правда, ДиегоРБакеро. 26.03.2019
  • Пробовал с версией UPDATE: October 2018, но результат неверен. Я получаю // {bar: 15, foo: 116, me: 75, you: 100}, но ожидаемый результат // {bar: 15, me: 75, you: 100, foo: 116} Порядок в основном основан на стоимости. (15,75,100,116). Не в ключе. (б, е, м, у) 09.07.2020
  • Обновление от июля 2020 года кажется неработающим, по крайней мере, в Chrome. Он просто выводит тот же порядок, что и ввод {"bar": 15, "foo": 116, "me": 75, "you": 100} 30.07.2020
  • Подтверждено: ваши решения 2018 и 2020 не сортируются правильно, как вы можете видеть в своих собственных ссылках Ramda REPL. Это не имеет ничего отношения к Chrome. 17.03.2021

  • 7

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

    Если вам нужно что-то упорядочить, используйте массив и метод Array.prototype.sort.

    01.07.2009
  • Обратите внимание, что по этому поводу довольно много споров. Большинство реализаций хранят список в том порядке, в котором были добавлены элементы. IIRC, Chrome - нет. Были споры о том, должен ли Chrome соответствовать другим реализациям. Я считаю, что объект JavaScript - это хэш, и не следует предполагать никакого порядка. Я считаю, что Python прошел тот же аргумент, и недавно был представлен новый упорядоченный хеш-подобный список. В большинстве браузеров вы МОЖЕТЕ делать то, что хотите, воссоздавая свой объект, добавляя элементы по отсортированному значению. Но не стоит. 01.07.2009
  • Редактировать. Chrome обычно поддерживает порядок, но не всегда. И вот соответствующая ошибка Chromium: code.google.com/p/chromium / issues / detail? id = 883 01.07.2009
  • Это сообщение об ошибке неоправданно, и именно те, кто полагался на недокументированное поведение, были с ошибками. Прочтите раздел 8.6 ECMASCript; в нем четко указано, что объект - это неупорядоченный набор свойств. Любой, кто обнаружил, что это не так в некоторых реализациях, а затем начал зависеть от этого поведения, зависящего от реализации, совершил большую ошибку, и им не следует пытаться свалить вину с себя. Если бы я был в команде Chrome, я бы пометил этот отчет об ошибке как недействительный, WontFix. 01.07.2009
  • Но зачем Chrome ломать страницы, работающие в других браузерах? Однако я согласен с твоим мнением. Не следует полагаться на порядок. 01.07.2009
  • EcmaScript 5 фактически определяет порядок перечисления как порядок вставки - отсутствие определения считается ошибкой спецификации в ES3. Стоит отметить, что спецификация EcmaScript определяет поведение, которое никто не сочтет разумным - например, поведение спецификации заключается в том, что во многих случаях возникают синтаксические ошибки во время выполнения, неправильное использование continue, break, ++, -, const и т. Д. В соответствии с согласно спецификации любой движок, который генерирует исключение до достижения этого кода, является неправильным 02.07.2009
  • @olliej - Не думаю, что это правильно. В спецификации говорится: Механика и порядок перечисления свойств (шаг 6.a в первом алгоритме, шаг 7.a во втором) не указаны. Это на странице 92 PDF окончательного проекта. 20.02.2012
  • @whitneyland - Вы совершенно правы, что ES5 не определял порядок для свойств объекта. ES2015 сделал это несколько лет спустя (это не просто порядок вставки, как указано выше в комментарии olliej), но исключил некоторые операции. Они не были исключены более поздними спецификациями. Здесь, в 2020 году, есть порядок, и он применяется к ожидаемым операциям (for-in, Object.keys и т. Д.), Но по-прежнему не стоит полагаться на него. :-) 20.10.2020

  • 8

    Хорошо, как вы, возможно, знаете, в javascript есть функция sort () для сортировки массивов, но ничего для объекта ...

    Итак, в этом случае нам нужно каким-то образом получить массив ключей и отсортировать их, поэтому apis большую часть времени предоставляет вам объекты в массиве, потому что Array имеет больше встроенных функций для игры с ними, чем литерал объекта, в любом случае, Быстрое соло использует Object.key, который возвращает массив ключей объекта, я создаю функцию ES6 ниже, которая выполняет эту работу за вас, она использует собственный Функции sort () и reduce () в javascript:

    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}
    

    Также таким образом основной объект не будет затронут, и мы фактически получим новый объект.

    Я также создаю изображение ниже, чтобы сделать шаги функции более понятными, на случай, если вам нужно немного изменить его, чтобы он работал по-своему:

    «Сортировка

    02.08.2017
  • Сортировка по ключу, а не по значению. 28.08.2017
  • @ROROROOROROR, это просто показатель того, как это работает, поскольку они не такие уж и разные, но все хорошо, я тоже добавлю сортировку по значению 28.08.2017
  • Сортировка по значению неверна, и это ваш набор данных. Измените c: 3 на c: 13, и вы увидите, как он развалится. 01.11.2017
  • @VtoCorleone Это просто естественная ошибка сортировки, на первом месте стоит 1, а не ошибка в представленном алгоритме. 23.04.2018

  • 9

    Обновление с помощью 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
    
    08.12.2016
  • Также в ES6 (ES2015): свойства объекта действительно имеют порядок (или есть средства доступа к ним в определенном порядке, в зависимости от вашей точки зрения). Если имена свойств являются строками и не похожи на индексы массива, порядок соответствует порядку, в котором они были добавлены к объекту. Этот порядок не указан для соблюдения for-in или Object.keys, но определен для соблюдения Object.getOwnPropertyNames и другими новыми методами доступа к массивам имен свойств. Так что это еще один вариант. 31.12.2016
  • Но где же операция "сортировка"? Они вообще не сортируются 06.02.2017
  • @Green Я думаю, что я хотел здесь выделить, что с Map у вас действительно есть структура данных, которая может храниться в отсортированном порядке (отсортировать ваши данные, просмотреть их и сохранить на карте), где, поскольку вам не гарантируется, что с объектами. 07.02.2017

  • 10

    Сортировка значений без нескольких циклов 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) 

    16.05.2019

    11

    Очень коротко и просто!

    var sortedList = {};
    Object.keys(list).sort((a,b) => list[a]-list[b]).forEach((key) => {
        sortedList[key] = list[key]; });
    
    23.08.2019

    12

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

    демонстрация

    17.09.2013

    13

    Я слежу за решением, данным 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
    }
    
    10.03.2013

    14

    Спасибо @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"}}

    17.10.2020

    15

    Это может быть простой способ обращаться с ним как с реальным упорядоченным объектом. Не уверен, насколько это медленно. также может быть лучше с циклом 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;
    };
    

    So

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

    16

    Объект отсортирован по значению (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;
    }
    
    06.04.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}]

    06.09.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}
    
    29.10.2018
  • Вы возвращаете задание в этом map, forEach было бы лучше 08.03.2019

  • 19

    Машинопись

    Следующая функция сортирует объект по значению или свойству значения. Если вы не используете 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 });
    
    26.09.2019
  • можно мне это в javascript, пожалуйста. 04.08.2020
  • Большое спасибо, это решение сработало для меня. Я использовал то же самое в Javascript без интерфейса словаря. const Country = {AD: {name: Andorra,}, AE: {name: United Arab Emirates,}, IN: {name: India,},} // Сортируем объект внутри объекта. var sortedMap = sort (Страны, val = ›val.name); // Преобразовать в объект. var sortedObj = {}; sortedMap.forEach ((v, k) = ›{sortedObj [k] = v}); console.log (sortedObj); Вывод: {AD: {name: Andorra}, IN: {name: India}, AE: {name: Объединенные Арабские Эмираты}} 17.10.2020

  • 20
    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 ] ]
    
    12.02.2020

    21

    Есть много способов сделать это, но, поскольку я не видел, чтобы они использовали 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);

    09.07.2020

    22

    много похожих и полезных функций: 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;
    }
    
    18.10.2015

    23

    Еще один пример:

    function sortObject(obj) {
      var arr = [];
      var prop;
      for (prop in obj) {
        if (obj.hasOwnProperty(prop)) {
          arr.push({
            'key': prop,
            'value': obj[prop]
          });
        }
      }
      arr.sort(function(a, b) {
        return a.value - b.value;
      });
      return arr; // returns array
    }
    var list = {
      car: 300,
      bike: 60,
      motorbike: 200,
      airplane: 1000,
      helicopter: 400,
      rocket: 8 * 60 * 60
    };
    var arr = sortObject(list);
    console.log(arr);

    03.06.2016

    24

    вот способ отсортировать объект и получить отсортированный объект взамен

    let sortedObject = {}
    sortedObject = Object.keys(yourObject).sort((a, b) => {
                            return yourObject[a] - yourObject[b] 
                        }).reduce((prev, curr, i) => {
                            prev[i] = yourObject[curr]
                            return prev
                        }, {});
    

    вы можете настроить функцию сортировки в соответствии с вашими требованиями

    14.07.2017
  • Отличный ответ. Спасибо! 25.08.2017

  • 25

    input - это объект, output - это объект, используя встроенную библиотеку lodash и js, с опциями по убыванию или возрастанию и не изменяет входной объект

    например, ввод и вывод

    {
      "a": 1,
      "b": 4,
      "c": 0,
      "d": 2
    }
    {
      "b": 4,
      "d": 2,
      "a": 1,
      "c": 0
    }
    

    Реализация

    const _ = require('lodash');
    
    const o = { a: 1, b: 4, c: 0, d: 2 };
    
    
    function sortByValue(object, descending = true) {
      const { max, min } = Math;
      const selector = descending ? max : min;
    
      const objects = [];
      const cloned = _.clone(object);
    
      while (!_.isEmpty(cloned)) {
        const selectedValue = selector(...Object.values(cloned));
        const [key, value] = Object.entries(cloned).find(([, value]) => value === selectedValue);
    
        objects.push({ [key]: value });
        delete cloned[key];
      }
    
      return _.merge(...objects);
    }
    
    const o2 = sortByValue(o);
    console.log(JSON.stringify(o2, null, 2));
    
    09.10.2019

    26

    мое решение с сортировкой:

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

    27

    Найти частоту каждого элемента и отсортировать по частоте / значениям.

    let response = ["apple", "orange", "apple", "banana", "orange", "banana", "banana"];
    let frequency = {};
    response.forEach(function(item) {
      frequency[item] = frequency[item] ? frequency[item] + 1 : 1;
    });
    console.log(frequency);
    let intents = Object.entries(frequency)
      .sort((a, b) => b[1] - a[1])
      .map(function(x) {
        return x[0];
      });
    console.log(intents);

    Выходы:

    { apple: 2, orange: 2, banana: 3 }
    [ 'banana', 'apple', 'orange' ]
    
    22.07.2020
  • Чтобы использовать то же самое с TypeScript, измените строку .sort ((a: any, b: any) = ›b [1] - a [1]), добавив любой тип к переменным. 22.07.2020

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

    Использованная литература:

    18.03.2021

    29

    Другой способ решить эту проблему: -

    var res = [{"s1":5},{"s2":3},{"s3":8}].sort(function(obj1,obj2){ 
     var prop1;
     var prop2;
     for(prop in obj1) {
      prop1=prop;
     }
     for(prop in obj2) {
      prop2=prop;
     }
     //the above two for loops will iterate only once because we use it to find the key
     return obj1[prop1]-obj2[prop2];
    });
    

    // res будет иметь массив результатов

    08.04.2014

    30

    Спасибо и продолжаем отвечать @Nosredna

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

    Object {6: Object, 7: Object, 8: Object, 9: Object, 10: Object, 11: Object, 12: Object}
       6: Object
       id: "6"
       name: "PhD"
       obe_service_type_id: "2"
       __proto__: Object
       7: Object
       id: "7"
       name: "BVC (BPTC)"
       obe_service_type_id: "2"
       __proto__: Object
    
    
        //Sort options
        var sortable = [];
        for (var vehicle in options)
        sortable.push([vehicle, options[vehicle]]);
        sortable.sort(function(a, b) {
            return a[1].name < b[1].name ? -1 : 1;
        });
    
    
        //sortable => prints  
    [Array[2], Array[2], Array[2], Array[2], Array[2], Array[2], Array[2]]
        0: Array[2]
        0: "11"
        1: Object
            id: "11"
            name: "AS/A2"
            obe_service_type_id: "2"
            __proto__: Object
            length: 2
            __proto__: Array[0]
        1: Array[2]
        0: "7"
        1: Object
            id: "7"
            name: "BVC (BPTC)"
            obe_service_type_id: "2"
            __proto__: Object
            length: 2
    
    14.05.2014

    31

    Попробуй это. Даже ваш объект не имеет свойства, на основе которого вы пытаетесь отсортировать, также будет обработано.

    Просто вызовите его, отправив свойство с объектом.

    var sortObjectByProperty = function(property,object){
    
        console.time("Sorting");
        var  sortedList      = [];
             emptyProperty   = [];
             tempObject      = [];
             nullProperty    = [];
        $.each(object,function(index,entry){
            if(entry.hasOwnProperty(property)){
                var propertyValue = entry[property];
                if(propertyValue!="" && propertyValue!=null){
                  sortedList.push({key:propertyValue.toLowerCase().trim(),value:entry});  
                }else{
                    emptyProperty.push(entry);
               }
            }else{
                nullProperty.push(entry);
            }
        });
    
          sortedList.sort(function(a,b){
               return a.key < b.key ? -1 : 1;
             //return a.key < b.key?-1:1;   // Asc 
             //return a.key < b.key?1:-1;  // Desc
          });
    
    
        $.each(sortedList,function(key,entry){
            tempObject[tempObject.length] = entry.value;
         });
    
        if(emptyProperty.length>0){
            tempObject.concat(emptyProperty);
        }
        if(nullProperty.length>0){
            tempObject.concat(nullProperty);
        }
        console.timeEnd("Sorting");
        return tempObject;
    }
    
    24.09.2014

    32

    Я сделал плагин только для этого, он принимает 1 аргумент, который является несортированным объектом, и возвращает объект, который был отсортирован по значению свойства. Это будет работать со всеми двухмерными объектами, такими как _1 _...

    var sloppyObj = {
        'C': 78,
        'A': 3,
        'B': 4
    };
    
    // Extend object to support sort method
    function sortObj(obj) {
        "use strict";
    
        function Obj2Array(obj) {
            var newObj = [];
            for (var key in obj) {
                if (!obj.hasOwnProperty(key)) return;
                var value = [key, obj[key]];
                newObj.push(value);
            }
            return newObj;
        }
    
        var sortedArray = Obj2Array(obj).sort(function(a, b) {
            if (a[1] < b[1]) return -1;
            if (a[1] > b[1]) return 1;
            return 0;
        });
    
        function recreateSortedObject(targ) {
            var sortedObj = {};
            for (var i = 0; i < targ.length; i++) {
                sortedObj[targ[i][0]] = targ[i][1];
            }
            return sortedObj;
        }
        return recreateSortedObject(sortedArray);
    }
    
    var sortedObj = sortObj(sloppyObj);
    
    alert(JSON.stringify(sortedObj));
    

    Вот демонстрация ожидаемой работы функции http://codepen.io/nicholasabrams/pen/RWRqve?editors=001

    22.09.2015

    33

    Используя query-js, вы можете сделать это следующим образом

    list.keys().select(function(k){
        return {
            key: k,
            value : list[k]
        }
    }).orderBy(function(e){ return e.value;});
    

    Вы можете найти вводную статью о query-js здесь

    18.06.2015

    34

    Не удалось найти ответ выше, который одновременно работал бы и был МАЛЕНЬКИМ, и поддерживал бы вложенные объекты (не массивы), поэтому я написал свой собственный :) Работает как со строками и ints.

      function sortObjectProperties(obj, sortValue){
          var keysSorted = Object.keys(obj).sort(function(a,b){return obj[a][sortValue]-obj[b][sortValue]});
          var objSorted = {};
          for(var i = 0; i < keysSorted.length; i++){
              objSorted[keysSorted[i]] = obj[keysSorted[i]];
          }
          return objSorted;
        }
    

    Использование:

        /* sample object with unsorder properties, that we want to sort by 
        their "customValue" property */
    
        var objUnsorted = {
           prop1 : {
              customValue : 'ZZ'
           },
           prop2 : {
              customValue : 'AA'
           }
        }
    
        // call the function, passing object and property with it should be sorted out
        var objSorted = sortObjectProperties(objUnsorted, 'customValue');
    
        // now console.log(objSorted) will return:
        { 
           prop2 : {
              customValue : 'AA'
           },
           prop1 : {
              customValue : 'ZZ'
           } 
        }
    
    27.04.2016
  • keysSorted сортируется в порядке возрастания sortValue, но поскольку объект javascript представляет собой неупорядоченный набор свойств, нет смысла пытаться упорядочить эти свойства 06.12.2017

  • 35
    function sortObjByValue(list){
     var sortedObj = {}
     Object.keys(list)
      .map(key => [key, list[key]])
      .sort((a,b) => a[1] > b[1] ? 1 : a[1] < b[1] ? -1 : 0)
      .forEach(data => sortedObj[data[0]] = data[1]);
     return sortedObj;
    }
    sortObjByValue(list);
    

    Github Gist Ссылка

    13.10.2018

    36

    Если у меня есть такой объект,

    var dayObj = {
                  "Friday":["5:00pm to 12:00am"] ,
                  "Wednesday":["5:00pm to 11:00pm"],
                  "Sunday":["11:00am to 11:00pm"], 
                  "Thursday":["5:00pm to 11:00pm"],
                  "Saturday":["11:00am to 12:00am"]
               }
    

    хочу отсортировать по дням,

    сначала у нас должен быть daySorterMap,

    var daySorterMap = {
      // "sunday": 0, // << if sunday is first day of week
      "Monday": 1,
      "Tuesday": 2,
      "Wednesday": 3,
      "Thursday": 4,
      "Friday": 5,
      "Saturday": 6,
      "Sunday": 7
    }
    

    Инициируйте отдельный объект sortedDayObj,

    var sortedDayObj={};
    Object.keys(dayObj)
    .sort((a,b) => daySorterMap[a] - daySorterMap[b])
    .forEach(value=>sortedDayObj[value]= dayObj[value])
    

    Вы можете вернуть sortedDayObj

    10.05.2018
  • это вообще не отвечает на вопрос OP 18.12.2019
  • @notnavindu .. Да, может быть, это не все, но есть более простое решение для этого, `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]]` 12.02.2020

  • 37
  • Просто и идеально! Это отвечает на вопрос. Спасибо. 27.04.2017
  • Порядок ключей не гарантируется в javascript, поэтому для меня это не работает, если ключи являются целыми числами или т.п. 29.05.2017
  • точно, ParoX. Это не работает правильно, если ключ имеет целочисленный тип. 29.01.2018

  • 38
  • Добро пожаловать в stackoverflow. В дополнение к предоставленному вами ответу, пожалуйста, рассмотрите возможность предоставления краткого объяснения того, почему и как это решает проблему. 13.05.2020
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..