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


699

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

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

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

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

4
Не только «сортировка», но, что более важно, сортировка чисел. Числа невосприимчивы к методу Javascripts Array.sort (), а это означает, что вам не просто нужно найти метод для сортировки свойств, но вам придется написать собственную функцию для сравнения числовых значений.
Сэмпсон

107
Прежде чем читать ответы: ответ - нет . Порядок свойств объекта является нестандартным в ECMAScript. Вы никогда не должны делать предположения о порядке элементов в объекте JavaScript. Объект - это неупорядоченная коллекция свойств. Ответы ниже показывают, как «использовать» отсортированные свойства, используя массивы, но никогда не меняйте порядок свойств самих объектов. Так что нет, это невозможно. Даже если вы строите объект с предварительно отсортированными свойствами, это не гарантирует, что они будут отображаться в том же порядке в будущем. Читать дальше :).
Говинд Рай

3
@GovindRai, однако, в реальных веб-приложениях мы перебираем коллекции объектов с идентификаторами в качестве ключей, и порядок важен при переводе в шаблоны HTML. Вы говорите, что у них нет порядка, я говорю, что у них есть именно тот порядок, который я вижу, когда console.log их в текущем браузере. И этот порядок может быть переупорядочен. Как только вы зациклились на них, у них есть заказ.
Задачи из

7
@GovindRai: теперь в спецификации есть способ доступа к свойствам в указанном порядке. Это хорошая идея? Почти наверняка нет. :-) Но это там, с ES2015.
TJ Crowder

7
Посетители 2019 года: проверьте этот ответ, Object.entriesоснованный на едва проголосованном ответе, который является самым чистым и наиболее читаемым современным состоянием после ES2017: stackoverflow.com/a/37607084/245966
jakub.g

Ответы:


707

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

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

24
Не могли бы вы изменить формулировку «вы можете перестроить» на «вы можете использовать массив для поддержания порядка ключей и извлечения значений из объекта»? Это не только нестандартно, как вы сами упомянули, это ошибочное предположение нарушается большим количеством браузеров, чем просто Chrome сегодня, поэтому лучше не поощрять пользователей пробовать это.
Волков Олег Викторович

32
Вот более компактная версия вашего кода. Object.keys (maxSpeed) .sort (function (a, b) {return - (maxSpeed ​​[a] - maxSpeed ​​[b])});
TheBrain

6
@TheBrain: просто добавить, keys()поддерживается только IE9 + (и другими современными браузерами), если это вызывает озабоченность. Также keys()исключает перечислимые свойства из цепочки прототипов элементов (в отличие от ...), но обычно это более желательно.
MrWhite

31
_.pairsпревращает объект в [[key1, value1], [key2, value2]]. Тогда назовите сортировку по этому вопросу. Тогда призовите _.objectэто, чтобы повернуть это назад.
Funkodebat

2
Мой проект требует объектных ключей для слияния, но также требует явной сортировки, поскольку метаданные управляют пользовательским интерфейсом. Я придерживался аналогичного подхода, только добавив проверку hasOwnProperty, чтобы избежать сканирования цепочки прототипов. Вот хорошая статья о переборе свойств объекта в JS hackernoon.com/…
Натан Аджерси

416

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

Вот еще один способ сделать то же самое, что и Бонна:

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


22
Похоже, что это сортировка по ключу, а не по значению, а это не то, что требовал вопрос?
Майкл

27
Он сортируется по значению и отображает ключи - но мы теряем значение счетчика при его печати, поскольку оно печатает только ключи.
Ханна

6
Порядок свойств объекта не гарантируется в JavaScript, поэтому сортировку следует выполнять в массив, а не в объект (который вы называете «ассоциативным массивом»).
Кристофер Мейерс

6
Не забывай keysSortedэто массив! Не объект!
Зеленый,

17
Если вы добавите .map(key => list[key]);в конец сортировки, он вернет весь объект, а не только ключ
Джеймс Моран

184

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

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
Сортировать по имени не следует substrиз первого символа; еще Dianaи Debraиметь неопределенный порядок. Кроме того, ваш byDateвид на самом деле использует num, а не born.
Лоуренс Дол

Это выглядит хорошо, но обратите внимание, что для сравнения строк вы можете просто использоватьx.localeCompare(y)
Jemar Jones

2
@JemarJones localCompareвыглядит очень полезной функцией! Просто отметьте, что он не будет поддерживаться в каждом браузере - IE 10 и менее, Safari Mobile 9 и менее.
неорганик

@inorganik Да, очень хорошая заметка для тех, кому нужна поддержка этих браузеров
Джемар Джонс,

1
Это массив Объектов, который не является запрашиваемым ОП (Объект с несколькими свойствами)
Жоао Пиментел Феррейра,

62

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

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


1
Как насчет массива объектов? [{name: Will}, {name: Bill}, {name: Ben}]
Уилл Хэнкок

1
Привет Уилл, вы можете использовать функцию localeCompare для этого сравнения. Добавил его в ответ выше.
Стано

Отличное решение. Сортировка строк требует возврата
pfwd

@ Stano Правильное и простое решение. Спасибо.
Абрар Хоссейн

49

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

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

как это может ответить на заголовок вопроса Sorting JavaScript Object by property value? Я думаю, вы неправильно поняли вопрос, поскольку вам нужно изменить исходный объект, а не создавать из него новый массив.
vsync

2
@vsync Этот ответ дает тот же результат, что и принятый ответ, но с меньшим количеством кода и без временной переменной.
Даррен Кук

3
FWIW, этот ответ чистый и единственный, который помог мне.
NetOperator Wibby

только в ff, not ie и chrome больше они не сортируют объекты автоматически. wtf
fb

Просто отметьте, что это не сохранит ключи.
Ваэль Виктус

40

«Стрелки» версия @marcusR «s ответа для справки

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 г. - возвращает отсортированный myObjобъект, определенный выше.

Object
 .keys(myObj)
 .sort((a, b) => myObj[a]-myObj[b])
 .reduce((_sortedObj, key) => ({
   ..._sortedObj, 
   [key]: myObj[key]
 }), {})

Попробуй это здесь!

ОБНОВЛЕНИЕ: октябрь 2018 - версия Object.entries

Object
 .entries(myObj)
 .sort()
 .reduce((_sortedObj, [k,v]) => ({
   ..._sortedObj, 
   [k]: v
 }), {})

Попробуй это здесь!


1
не работает дляvar myObj = {"1": {"Value": 40}, "2": {"Value": 10}, "3": {"Value": 30}, "4": {"Value": 20}};
Роханил

5
Вопрос ОП, наряду с этим ответом, не содержит вложенных объектов. @Rohanil Может быть, вы захотите задать другой вопрос вместо голосования с понижением. Ваш вложенный объект с различными типами, очевидно, нуждается в большем, чем это обеспечивает решение
Джейсон Дж. Натан

Просто обратите внимание: ваши обновления не будут работать на самом деле. По крайней мере, не везде и не из-за entries. Согласно стандарту, объект - это неупорядоченный набор свойств . Что ж, это означает, что если вы пытаетесь создать новый объект после сортировки его по значению свойства или чему-либо еще, порядок ключей свойства снова становится неопределенным. Например, Chrome по умолчанию упорядочивает ключи свойств, поэтому каждая попытка упорядочить их по-другому бесполезна. Ваш единственный шанс - получить «индекс», основанный на ваших предпочтениях при оформлении заказа, и соответственно пройтись по оригинальному объекту.
ZorgoZ

Да @ZorgoZ, вы правы, и многие люди упоминали об этом в этом посте. Большую часть времени мы используем эту функцию как преобразование перед преобразованием в другой тип (например, JSON) или перед другой функцией приведения. Если целью является изменение объекта после этого, тогда могут быть неожиданные результаты. Я имел успех с этой функцией через двигатели.
Джейсон Дж. Натан

Примечание: вы не хотите использовать sort()наObject.entries()
Solvitieg

36

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

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


4
Обратите внимание, что об этом было много споров. Большинство реализаций хранят список в порядке добавления элементов. IIRC, Chrome нет. Был спор о том, должен ли Chrome соответствовать другим реализациям. Я считаю, что объект JavaScript - это хеш, и порядок не должен быть принят. Я считаю, что Python прошел через тот же аргумент, и недавно был представлен новый упорядоченный список, похожий на хэш. Для большинства браузеров вы МОЖЕТЕ делать то, что вы хотите, воссоздавая свой объект, добавляя элементы по отсортированному значению. Но ты не должен.
Носредна

Редактировать. Хром обычно следит за порядком, но не всегда. А вот соответствующая ошибка Chromium: code.google.com/p/chromium/issues/detail?id=883
Носредна

6
Этот отчет об ошибке неоправдан, и те, кто полагался на недокументированное поведение, являются теми с ошибками. Прочитайте раздел ECMASCript 8.6; в нем четко говорится, что «Объект - это неупорядоченная коллекция свойств». Любой, кто обнаружил, что в нескольких реализациях это не так, а затем начал зависеть от этого поведения, специфичного для реализации, совершил большую ошибку, и ему не следует пытаться свалить вину с себя. Если бы я был в команде Chrome, я бы пометил этот отчет об ошибке как «Invalid, WontFix».
NickFitz

8
EcmaScript 5 фактически определяет порядок перечисления как порядок вставки - отсутствие определения считается ошибкой спецификации в ES3. Стоит отметить, что спецификация EcmaScript определяет поведение, которое никто не счел бы нормальным - например, поведение спецификации заключается в том, что синтаксические ошибки во многих случаях вызываются во время выполнения, некорректное использование continue, break, ++, -, const и т. Д. Согласно к спецификации любой движок, который выдает исключение до достижения этого кода, неверен
olliej

4
@olliej - я не думаю, что это правильно. В спецификации говорится: «Механизм и порядок перечисления свойств (шаг 6.a в первом алгоритме, шаг 7.a во втором) не указан». Это на странице 92 PDF окончательного проекта.
Whitneyland

25

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

Таким образом, в этом случае нам нужно каким-то образом получить массив ключей и отсортировать их, вот почему apis дает вам объекты в массиве большую часть времени, потому что Array имеет больше встроенных функций для работы с ними, чем в любом случае литерал объекта, быстрое решение заключается в использовании Object.key, который возвращает массив ключей объекта, я создаю ниже функцию ES6, которая выполняет эту работу за вас, она использует встроенные функции sort () и redu () в 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}

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

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

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


4
Это сортировка по ключу, а не по значению.
ROROROOROROR

@ROROROOROROR, это просто указание , как это работает , поскольку они не отличаются, но все хорошо, я буду добавлять сортировку по значению тоже
Alireza

1
Сортировка по значению неверна, и это ваш набор данных. Перейдите c: 3на c: 13и вы увидите, что он развалится.
VtoCorleone

1
@VtoCorleone Это просто естественная ошибка сортировки, 1 на первом месте, а не недостаток в алгоритме, как представлено.
Майкл Райан Сойло

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

Просто и отлично! Это отвечает на вопрос. Спасибо.
Аджай Сингх

Порядок ключей не гарантируется в javascript, поэтому для меня это не работает, если ключи целые числа или тому подобное
ParoX

точно, ParoX. Это не работает правильно, когда ключ имеет целочисленный тип.
Джунгвон Джин

8

Обновление с 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

Также в ES6 (ES2015): Свойства объекта действительно имеют порядок (или есть средство доступа к ним в определенном порядке, в зависимости от вашей точки зрения). Если имена свойств являются строками и не похожи на индексы массива, порядок - это порядок, в который они были добавлены к объекту. Этот порядок не указан должен соблюдаться for-inили Object.keys, но это определяется уважаться Object.getOwnPropertyNamesи другими новыми методами для доступа к имени свойства массивов. Так что это еще один вариант.
TJ Crowder

Но где операция `sort '? Они совсем не отсортированы
Green

@ Зеленый Я думаю, что я хотел бы подчеркнуть, что у Mapвас действительно есть структура данных, которая может хранить в отсортированном порядке (сортировать ваши данные, проходить по ним и сохранять их на карте), где вы не гарантируете, что с объекты.
julianljk

6

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

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


6

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

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

5

Я следую решению, данному 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
}

4

Сортировать значения без нескольких циклов for (для сортировки по ключам изменить индекс в обратном вызове sort на «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) 


2

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

2
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
   } , [])

output = [{p: 8}, {c: 2}, {b: 1}, {g: 1}]


2

На всякий случай, кто-то ищет сохранение объекта (с ключами и значениями), используя ссылку на код @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
Вы возвращаете задание в этом map, forEachбыло бы лучше
DiegoRBaquero


1

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

1

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

1

Вот еще один пример:

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


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

1

Машинопись

Следующая функция сортирует объект по значению или по свойству значения. Если вы не используете 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 объект, который сохраняет порядок сортировки.

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

var sortedObj = {} as any;
sortedMap.forEach((v,k) => { sortedObj[k] = v });

1

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

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

1

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

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

Пожалуйста, отформатируйте ваш код как код
Итамар Мушкин

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

1
Добро пожаловать в stackoverflow. В дополнение к ответу, который вы предоставили, рассмотрите краткое объяснение, почему и как это решает проблему.
jtate

0

Еще один способ решить эту проблему:

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 будет иметь массив результатов


0

Спасибо и продолжайте отвечать @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

0

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

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

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;
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.