Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Неправильно сортируется обьект (https://javascript.ru/forum/dom-window/84291-nepravilno-sortiruetsya-obekt.html)

dimas15 30.07.2022 19:04

Неправильно сортируется обьект
 
Сортирую объект, но на выходе не сортируется правильно.
Нужно так [А-ЯA-Z0-9] , а получается только так [0-9А-ЯA-Z] . Идей вообще никаких, уже все перепробовал.
https://codepen.io/dmgrig/pen/LYdeGVy?editors=0011

рони 30.07.2022 19:25

Цитата:

Сообщение от dimas15
Сортирую объект,

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

dimas15 30.07.2022 19:49

Цитата:

Сообщение от рони (Сообщение 546990)
не занимайтесь ерундой, ничего не получится, отсортировать можно только массив.

по факту сортирую ключи массива.

рони 30.07.2022 19:51

Цитата:

Сообщение от dimas15
по факту сортирую ключи массива.

зачем сортировать отсортированное?
var nws = [];
//возвращаем отсортированный исходный массив
sortmas.forEach((key)=> {
  nws.push(key) ;
});

console.log("Получается так:\t\t"+nws);

рони 30.07.2022 20:01

dimas15,
какая задача, что нужно получить из исходного массива?

dimas15 30.07.2022 20:03

Цитата:

Сообщение от рони (Сообщение 546997)
зачем сортировать отсортированное?
var nws = [];
//возвращаем отсортированный исходный массив
sortmas.forEach((key)=> {
  nws.push(key) ;
});

console.log("Получается так:\t\t"+nws);

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

dimas15 30.07.2022 20:05

Цитата:

Сообщение от dimas15 (Сообщение 546999)
Я беру массив ключей из обьекта, потом сопоставляю эти ключи с обьектом чтобы вернуть отсортированный обьект.

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

рони 30.07.2022 20:11

dimas15,
Цитата:

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

???

цель ваших манипуляций в итоге?

dimas15 30.07.2022 20:36

Цитата:

Сообщение от рони (Сообщение 547001)
dimas15,

???

цель ваших манипуляций в итоге?

Получить в обьекте отсортированные ключи по алфавиту: кирилица,латиница, цифры

рони 30.07.2022 20:38

dimas15,
ключи объекта в объекте не сортируются!!!

рони 30.07.2022 20:39

dimas15,
сортируйте массив!!!

dimas15 30.07.2022 20:43

Цитата:

Сообщение от рони (Сообщение 547003)
dimas15,
ключи объекта в объекте не сортируются!!!

Согласен, я взял массив из обьекта который состоит из ключей, потом отсортировал его и сопоставил этот массив с массивом в обьекте.

рони 30.07.2022 20:54

dimas15,
я пас, может кто-то другой вам поможет ...

рони 30.07.2022 21:50

dimas15,
попробуем ещё раз)))
чем вас сортировка массива не устраивает? зачем надо игры с объектами и ключами устраивать?

dimas15 30.07.2022 22:23

Цитата:

Сообщение от рони (Сообщение 547007)
dimas15,
попробуем ещё раз)))
чем вас сортировка массива не устраивает? зачем надо игры с объектами и ключами устраивать?

Делаю все для этого:

Все продукты А-Я

Все А Б В Г Д Е Ж З И К Л М Н О П Р С Т У
Ф Х Ц Ш Щ Э A B C D E F G H I K L M N O P Q
R S T U V W 2

2
2-Меркапт

А
Агар
Агидол-2
...

Делаю все это из массива обьектов:

[ {
"name": "2-этилгексил",
"url": "2-этилг",
"id": 1020
},
{
"name": "Acralen",
"url": "Acra",
"id": 193
},
{
"name": "Acr5028",
"url": "Acr",
"id": 1295
},
...
...
....
]

Преобразую в это:

[ 2: [{
"name": "2-этилге",
"url": "2-этилгек",
"id": 1020
},...],
A: [ {
"name": "Acralen",
"url": "Acralen",
"id": 193
},
{
"name": "Acro5028",
"url": "Acro5028",
"id": 1295
},...]
.....]

И сортирую этот обьект массивов по ключам 2,А,Б,A,D...
В итоге все сортируется почти так как надо, только цифры идут первыми а они должны идти в конце.
"Нужно так: А,Б,В,Г,Д,Е,Ж,З,И,К,Л,М,Н,О,П,Р,С ,Т,У,Ф,Х,Ц,Ш,Щ,Э,A,B,C,D,E,F,G,H,I,K,L,M,N ,O,P,Q,R,S,T,U,V,W,2"

"Получается так(цифры сортируются в начале а не в конце массива): 2,А,Б,В,Г,Д,Е,Ж,З,И,К,Л,М,Н,О,П,Р, С,Т,У,Ф,Х,Ц,Ш,Щ,Э,A,B,C,D,E,F,G,H,I,K,L,M ,N,O,P,Q,R,S,T,U,V,W"


//перестраиваю массив обьектов.
const modmas = obj.reduce((a, b) => { 
const first = b.name[0].toUpperCase();
  if (!a[first]) {
    a[first] = [];
  }         
  a[first].push(b);
  return a;
},{}) 


//проверяю тип данных и преобразую числа из string в number 
var arr = [];
var mm = Object.keys(modmas);
var length = mm.length;
for (var i = 0; i < length; i++){
  if (!isNaN(mm[i]) === true) {
    arr.push(Number(mm[i]));
  } else {
    arr.push(mm[i]);
  }
}

//сортирую 
const collator = new Intl.Collator('ru');
const sortmas = arr.sort(function (a, b) {
  if(isNaN(a) && !isNaN(b)){
    return -1;
  }else if(!isNaN(a) && isNaN(b)){
    return 1;
  }
  return collator.compare(a, b);
  /*return a.localeCompare(b, undefined, {
    numeric: true,
    sensitivity: 'base'
  });*/
})

var nws = {};
//возвращаем отсортированный исходный массив с вложенными данными
sortmas.forEach((key)=> {
  nws[key] = modmas[key];  
});

console.log(":\t\t"+Object.keys(nws));

рони 30.07.2022 22:28

Цитата:

Сообщение от dimas15
Преобразую в это:

[ 2: [{

это бред
лучше так
[{first, data : []} , {first, data : []}...., {first : "2", data : []}]

voraa 30.07.2022 22:40

Цитата:

Сообщение от dimas15
В итоге все сортируется почти так как надо

А как вы это определяете?
Если проходить объект через for in поряок будет один (всегда сначала все численные ключи в порядке возрастания, потом остальные ключи в порядке их добавления в объект. Такой порядок не определен в спецификации, но его придерживаются все браузеры), если смотреть в отладчике, то порядок будет другой (отсортирован по алфавиту)

рони 30.07.2022 22:45

dimas15,
const collator = new Intl.Collator(["ru", "en"], {
            numeric: true
        });
        let arr = obj.slice(0).sort((a, b) => {
                let numA = (/^\d+/).test(a.name),
                    numB = (/^\d+/).test(b.name);
                if (numA && !numB) return 1;
                if (!numA && numB) return -1;
                return collator.compare(
                    a.name,
                    b.name
                )
            }

        );
        const modmas = [];
        let temp = {};
        for (const el of arr) {
            const first = el.name[0].toUpperCase();
            if (temp.first != first) {
                temp = {
                    first,
                    data: []
                };
                modmas.push(temp)
            };
            temp.data.push(el)
        }
        console.log(modmas);
        const keys = modmas.map(({first}) => first);
        console.log(keys);

dimas15 30.07.2022 22:47

Цитата:

Сообщение от voraa (Сообщение 547010)
А как вы это определяете?
Если проходить объект через for in поряок будет один (всегда сначала все численные ключи в порядке возрастания, потом остальные ключи в порядке их добавления в объект), если смотреть в отладчике, то порядок будет другой (отсортирован по алфавиту)

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

voraa 30.07.2022 22:57

Цитата:

Сообщение от dimas15
По алгоритму сортировки

Как вы узнаете, в каком порядке у вас расположились ключи?

Еще раз повторю
Цитата:

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


dimas15 31.07.2022 21:03

Цитата:

Сообщение от voraa (Сообщение 547013)
Как вы узнаете, в каком порядке у вас расположились ключи?

Еще раз повторю

Типа ничего больше не сделать?

рони 31.07.2022 21:06

Цитата:

Сообщение от dimas15
Типа ничего больше не сделать?

чем код #18 не устраивает?

dimas15 31.07.2022 21:30

Цитата:

Сообщение от voraa (Сообщение 547013)
Как вы узнаете, в каком порядке у вас расположились ключи?

Еще раз повторю

Цитата:

Сообщение от рони (Сообщение 547025)
чем код #18 не устраивает?

Отличное решение, устраивает, спасибо. И кода намного меньше чем у меня.

Aetae 31.07.2022 22:44

Цитата:

Сообщение от voraa (Сообщение 547010)
всегда сначала все численные ключи в порядке возрастания, потом остальные ключи в порядке их добавления в объект. Такой порядок не определен в спецификации, но его придерживаются все браузеры)

Вообще вроде определён именно так в последней спеке.
И это меня каждый раз как об этом вспоминаю вводит в состояния бешенства.) Каким безумным извращенцем надо было быть чтобы такое придумать и главное зачем?! Уму непостижимо. Чем им плох был изначальный вариант с простым порядком по мере добавления...

Alexandroppolus 01.08.2022 07:49

Aetae,

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

voraa 01.08.2022 09:59

Цитата:

Сообщение от Aetae
Вообще вроде определён именно так в последней спеке.

Вроде нет
ECMAScript 2023 https://tc39.es/ecma262/#sec-enumera...ect-properties
Так и сказано
14.7.5.9
Цитата:

The mechanics and order of enumerating the properties is not specified but must conform to the rules specified below.
rules specified below касаются удаления и добавления свойств во время итерации. Про порядок ни слова.

Aetae 01.08.2022 14:13

Цитата:

Сообщение от Alexandroppolus (Сообщение 547038)
Aetae,

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

Не согласен. ИМХО, язык такого высокого уровня как js должен преследовать в первую очередь интуитивность и удобство, пусть даже ценой небольшой просадки производительности или переусложнённой внутренней механики.
Текущая реализация нифига не интуитивна и нифига не удобна, реализация с рандомным порядком - также нифига не интуитивна и не удобна. Такие дела.

В седой древности подобных топиков тоже хватало, только касались они как раз НЕгарантированого порядка.
Недолгое затишье было только когда на некоторое время все договорились просто делать по мере добавления, но всё быстро снова сломали.)

Цитата:

Сообщение от voraa (Сообщение 547040)
Вроде нет
ECMAScript 2023 https://tc39.es/ecma262/#sec-enumera...ect-properties
Так и сказано
14.7.5.9
rules specified below касаются удаления и добавления свойств во время итерации. Про порядок ни слова.

Это описывается тут: https://tc39.es/ecma262/#sec-ordinaryownpropertykeys

Alexandroppolus 01.08.2022 15:47

Цитата:

Сообщение от Aetae
реализация с рандомным порядком - также нифига не интуитивна и не удобна.

ну, видимо, у всех по-разному, дело вкуса :)

я вообще долгое время не знал, что в объектах (да и в Map) может быть какой-то порядок, и всегда для таких задач пользовался массивами - там порядок задан явно.

MallSerg 02.08.2022 14:05

Цитата:

Сообщение от Aetae
Чем им плох был изначальный вариант с простым порядком по мере добавления...

Изначального варианта вообще не было но первые реализации именно так и поступали и в целях соблюдения обратной совместимости это было общепринятой нормой.
Новый вариант правил размещения позволяет размещать объекты в памяти с применением реляционной алгебры в частности V8 использует красно черные бинарные деревья что позволяет математически оптимально размещать и использовать данные.

Это сделано с целью упрощения реализации позволило удалить из движка JS отдельный не нужный механизм хранящий ссылки на данные, порядок их размещения и данные индексации.

В общем сделали протестили и продавили новый вариант в стандарт.


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