Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Помогите отсортировать многомерный объект! (https://javascript.ru/forum/misc/76713-pomogite-otsortirovat-mnogomernyjj-obekt.html)

рони 05.02.2019 23:25

AntonMs,
var obj = {
b:{"param1" : 11, "param2": 22, "param3" : 33},
a:{"param1" : 1, "param2": 2, "param3" : 3},
c:{"param1" : 111, "param2": 222, "param3" : 333}
};

function fn(obj, name)
{
   return Object.keys(obj).sort((a,b)=> obj[a][name] - obj[b][name] )
}

alert(fn(obj, "param2"));

Malleys 06.02.2019 02:05

var a = {
	a: { param1: 1,   param2: 22,  param3: 3   },
	b: { param1: 11,  param2: 2,   param3: 33  },
	c: { param1: 111, param2: 222, param3: 333 }
};

// ключи оригинального объекта
alert(Object.entries(a).map(([key]) => key).join(" > "));

// создадим отсортированный объект
var aSorted = Object.entries(a)
	.sort(([, a], [, b]) => a.param2 > b.param2 ? 1 : -1)
	.reduce((m, [k, v]) => ({ ...m, [k]: v }), {})

// ключи отсортированного объекта
alert(Object.entries(aSorted).map(([key]) => key).join(" > "));


Ключи объекта не должны быть строками, которые могут быть приведены к целочисленному индексу (ecma-international.org/ecma-262/9.0/)

Цитата:

Сообщение от AntonMs
На данный момент задача именно такая. Вот к примеру объект, если его перебирать то сначала будет "а". А нужно что-бы b > a > c.

В том примере вы ничего не перебираете!

var a = {
	b: { param1: 11,  param2: 2,   param3: 33  },
	a: { param1: 1,   param2: 22,  param3: 3   },
	c: { param1: 111, param2: 222, param3: 333 }
};

for(const [key, value] of Object.entries(a)) {
	alert(key);
}

AntonMs 07.02.2019 00:07

Цитата:

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

рони 07.02.2019 00:20

Цитата:

Сообщение от AntonMs
я же пришел с другой задачей сюда...

обьект не сортируют, можно создать новый с необходимой структурой(смотри пост #12), но это бесполезно, браузер не обязан учитывать порядок ключей.

AntonMs 07.02.2019 00:22

Malleys, спасибо, буду разбираться.

AntonMs 07.02.2019 00:49

рони, я понял, объекты это чисто для хранения информации, там нет учета индексов.

Malleys 07.02.2019 05:06

Цитата:

Сообщение от AntonMs
объекты это чисто для хранения информации, там нет учета индексов.

Цитата:

Сообщение от рони
браузер не обязан учитывать порядок ключей

Ключи вы можете получить при помощи метода Object.keys или Object.entries

Посмотрев определение, например, Object.entries, в спецификации (пункт 19.1.2.5), вы увидите, что для получения списка ключей/значении используется внутренний метод EnumerableOwnPropertyNames, в определении которого (пункт 7.3.21) видно, что на объекте вызывается внутренний метод [[OwnPropertyKeys]], в определении которого(9.1.11 и 9.1.11.1) видно, в каком порядке строится список ключей.

Сначала добавляются ключи, чьи строковые представления могут быть приведены к целочисленному значению, в возрастающем порядке их численных значении.

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

Затем добавляются ключи типа Symbol, в порядке их создания.

Хотя в целом, вы не можете получить ключи в порядке создания, но договорившись, что ключи будут только строками не приводимыми к целочисленному значению(я уже это писал выше в №12), вы всё-таки получите ключи в порядке создания!

Если вам нужен только вызов внутреннего [[OwnPropertyKeys]], то используйте Reflect.ownKeys

alert(Reflect.ownKeys({ b: 1, a: 2, c: 3 }).join(" > "))

AntonMs 08.02.2019 22:14

Malleys, ваш пример работает, но к сожалению я его не понимаю, и к тому же у моего объекта цифры в именах вместо примера с "a, b, c"? И кстати я эти заклинания вообще не понимаю "m, [k, v]) => ({ ...m, [k]: v }), {}", а это "[, b]" вообще работать не должно вроде :cray: Это магия или я нуб!

Malleys 09.02.2019 12:03

Цитата:

Сообщение от AntonMs
к тому же у моего объекта цифры в именах

Если у вас ключи не представляют натуральные числа, составленные только из "0123456789", то вы можете использовать то, что описано мной выше. Также можно те цифры заменить на другие, типа "④⑥" , "❹❻", "𝟓𝟔", "𝟡𝟜", "𝟥𝟩", "𝟮𝟳" или "𝟸𝟼"

Цитата:

Сообщение от AntonMs
я эти заклинания вообще не понимаю... Это магия...

Вы можете прочитать об этом, например, в учебнике Ильи Кантора на русском языке...
https://learn.javascript.ru/destructuring
https://learn.javascript.ru/es-function
https://learn.javascript.ru/es-object

Или может всё-таки заменить объект на массив пар?
Т. е. вместо { b: {}, a: {}, c: {}} у вас будет [["b", {}], ["a", {}], ["c", {}]].

Этот массив пар вы можете передать конструктору Map. new Map([["b", {}], ["a", {}], ["c", {}]])
Перебор осуществляется в порядке вставки. Объекты типа Map гарантируют это, в отличие от объектов типа Object.

Это тоже не магия, читайте в учебнике Ильи Кантора https://learn.javascript.ru/set-map

AntonMs 09.02.2019 13:16

Цитата:

можно те цифры заменить на другие
Цитата:

Или может всё-таки заменить объект на массив пар?
Дело в том что желательно построить алгоритм так чтобы тот объект не менять. Есть объект > далее из него генерится столбчатая диаграмма по порядку, но нужно что-бы была возможность по "param2" или "param3" по выбору.

По поводу "магии" то меня сбили с толку конструкции деструктуризации, не сталкивался с ними раньше, спасибо за ссылку.


Часовой пояс GMT +3, время: 23:03.