Сортування властивостей об'єкта за значеннями


697

Якщо у мене є об’єкт 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.logging їх у поточному браузері. І це замовлення може переробити. Як тільки ви перейдете на них, вони отримують наказ.
Проблеми від

7
@GovindRai: Тепер у специфікації є спосіб доступу до властивостей у визначеному порядку. Це гарна ідея? Майже точно не. :-) Але це там, станом на ES2015.
TJ Crowder

7
2019 відвідувачів: перевірити це ледь upvoted Object.entries-відповідь , який є найчистішим і самим читаним станом мистецтва , так як ES2017: stackoverflow.com/a/37607084/245966
jakub.g

Відповіді:


706

Перемістіть їх до масиву, відсортуйте цей масив та використовуйте цей масив для своїх цілей. Ось таке рішення:

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 (функція (a, b) {return - (maxSpeed ​​[a] - maxSpeed ​​[b])});
TheBrain

6
@TheBrain: Додамо, keys()підтримується лише IE9 + (та іншими сучасними браузерами), якщо це викликає занепокоєння. Також keys()виключає численні властивості з ланцюга прототипу елементів (на відміну від..in) - але це, як правило, більш бажано.
MrWhite

31
_.pairsперетворює об’єкт у [[key1, value1], [key2, value2]]. Тоді зателефонуйте сортувати за цим. Потім зателефонуйте, _.objectщоб повернути його назад.
Функодебат

2
Мій проект вимагає об'єктних ключів для чистого злиття, але також вимагає явного сортування, оскільки метадані керують інтерфейсом користувача. Я дотримувався аналогічного підходу, лише додав перевірку hasOwnProperty, щоб уникнути повзання по прототипу ланцюга. Ось хороша стаття про повторення властивостей об’єктів у JS hackernoon.com/…
Nathan Agersea

416

Ми не хочемо дублювати всю структуру даних або використовувати масив там, де нам потрібен асоціативний масив.

Ось ще один спосіб зробити те ж саме, що і 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


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)
Джемар Джонс

2
@JemarJones localCompareвиглядає як дуже корисна функція! Зауважте лише, що він підтримуватиметься не в кожному браузері - IE 10 і менше, Safari Mobile 9 і менше.
inorganik

@inorganik Так, дуже хороша примітка для тих, хто потребує підтримки цих браузерів
Jemar Jones

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 Правильне та просте рішення. Дуже дякую.
Абрар Хоссейн

48

Представляє 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, не тобто, ні в хромі, вони сортують об'єкти автоматично. wtf
fb

Просто зауважте, що це не збереже ключі.
Vael Victus

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 пройшов через той же аргумент, і нещодавно введений новий упорядкований хеш-список. У більшості браузерів ви МОЖЕТЕ робити все, що завгодно, відтворюючи об’єкт, додаючи елементи за відсортованим значенням. Але ти не повинен.
Nosredna

Редагувати. Chrome зазвичай підтримує порядок, але не завжди. А ось відповідна помилка Chromium: code.google.com/p/chromium/isissue/detail?id=883
Nosredna

6
Цей звіт про помилки є невиправданим, і ті, хто покладався на незадокументовану поведінку, - це ті, хто має помилки. Прочитайте розділ 8.6 ECMASCript; в ньому чітко зазначено, що "Об'єкт - це не упорядкована колекція властивостей". Той, хто виявив, що це не виглядає таким чином у кількох реалізаціях, а потім почав залежати від поведінки, що залежить від конкретної реалізації, зробив велику помилку, і вони не повинні намагатися перекласти вину з себе. Якби я був у команді Chrome, я б позначив цей звіт про помилку як "Недійсний, WontFix".
NickFitz

8
EcmaScript 5 фактично визначає порядок перерахування як порядок вставки - відсутність визначення вважається специфічною помилкою в ES3. Варто зауважити, що специфікація EcmaScript визначає поведінку, яку ніхто не вважатиме розумною - наприклад, специфіка поведінки полягає в тому, що помилки синтаксису в багатьох випадках кидаються під час виконання, неправильне використання продовження, перерви, ++, -, const тощо тощо спец. будь-який двигун, який кидає виняток, перш ніж досягти цього коду, невірний
olliej

4
@olliej - Я не думаю, що це правильно. Специфікація говорить: "Механіка та порядок перерахування властивостей (крок 6.a у першому алгоритмі, крок 7.a у другому) не вказані". Це на сторінці 92 PDF-документа остаточного проекту.
Уїтніленд

25

Добре , як ви знаєте, javascript має функцію sort () для сортування масивів, але нічого для об’єкта ...

Тож у такому випадку нам потрібно якось отримати масив ключів і сортувати їх, тому причина apis дає вам об’єкти в масиві більшу частину часу, тому що у Array є більш рідні функції, щоб грати з ними, ніж об'єкт буквальний, в будь-якому випадку, для швидкого солотування використовується Object.key, який повертає масив об’єктних клавіш, я створюю функцію ES6, під якою виконує завдання для вас, він використовує нативні функції sort () та зменшує () функції у 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, це лише вказівка ​​на те, як це працює, оскільки вони не такі вже й різні, але все добре, я додам також сортування за значенням
Аліреза

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. Це не працює правильно, коли ключ є цілим типом.
jungwon jin

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

Але де операція `сортування '? Вони взагалі не сортуються
Зелений

@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 (для сортування за клавішами змінити індекс у зворотному порядку виклику на "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

Це може бути простим способом поводження з ним як із реальним упорядкованим об’єктом. Не впевнений, наскільки це повільно. також може бути краще з циклом час.

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

вихід = [{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

Наступна функція сортує об’єкт за значенням або властивістю значення. Якщо ви не використовуєте 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 });

1

вхід - це об'єкт, вихід - об'єкт, використовуючи вбудовану liash & js lib, з опцією низхідного або висхідного рівня, і не мутує вхідний об'єкт

наприклад вхід і вихід

{
  "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.