Сортировка объекта в javascript

178
03 февраля 2020, 21:20

Есть такой объект:

data['params']['last_name']['property_xxc'] = 'abcd';
data['params']['last_name']['sort_index'] = 2;
data['params']['name']['property_erw'] = 'abcd';
data['params']['name']['sort_index'] = 5;
data['params']['date']['property_xxc'] = 'abcd';
data['params']['date']['sort_index'] = 3;

Этот объект с такой глубокой вложенностью, нужно отсортировать по полу sort_index, в итоге нужно получить такой объект:

data['params']['name']['property_erw'] = 'abcd';
data['params']['name']['sort_index'] = 5;
data['params']['date']['property_xxc'] = 'abcd';
data['params']['date']['sort_index'] = 3;
data['params']['last_name']['property_xxc'] = 'abcd';
data['params']['last_name']['sort_index'] = 2;

Пробовал отсортировать с помощью sort() так:

var compareData = (a, b) =>{
     return a.sort_index - b.sort_index;
};

Но, ничего не вышло. Подскажите как сделать такую сортировку?

Answer 1

Если надо изменить порядок следования свойств в объекте и в коде на javascript есть следующие строки

data['params']['last_name']['property_xxc'] = 'abcd';
data['params']['last_name']['sort_index'] = 2;
data['params']['name']['property_erw'] = 'abcd';
data['params']['name']['sort_index'] = 5;
data['params']['date']['property_xxc'] = 'abcd';
data['params']['date']['sort_index'] = 3;

то это значит, что в памяти находится следующий объект:

var data = {
    'params': {
        'last_name': {
            'property_xxc': 'abcd',
            'sort_index': 2
        },
        'name': {
            'property_erw': 'abcd',
            'sort_index': 5
        },
        'date': {
            'property_xxc': 'abcd',
            'sort_index': 3
        }
    }
};

Проверить это легко. Например, так

try { data['params']['last_name']['property_xxc'] = 'abcd'; } 
catch(e) { alert(e); }   // alert не появится, значит все правильно  

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

var result = { 'params': {} };
Object.keys(data.params).sort(function (a, b) {
    return data.params[b].sort_index - data.params[a].sort_index;
}).forEach(function (v) { result.params[v] = data.params[v]; });

В result получим свойства в необходимом порядке. Это можно проверить, вызвав JSON.stringify(result), получим

{
  "params": {
     "name": {
        "property_erw": "abcd",
        "sort_index": 5
     },
     "date": {
        "property_xxc": "abcd",
        "sort_index": 3
     },
     "last_name": {
        "property_xxc": "abcd",
        "sort_index": 2
     }
   }
}

Хотя это и можно сделать, но менять порядок свойств в объекте обычно не надо, но может понадобиться, например, для кодогенерации. Например, если надо сериализовать объект в JSON файл, который будет редактироваться вручную (например, в Visual Studio 2015 используются конфигурационные файлы project.json).

Answer 2

Ваша структура данных — это не массив, а объект. Порядок следования элементов в объекте не гарантирован спецификацией (по крайней мере до ES2015 и даже там есть тонкости с целочисленными ключами), поэтому в общем случае его сортировка не имеет смысла. Попытка вызвать метод sort у объекта закончится неудачей, поскольку у него попросту нет такого метода.

Как следствие, если вы хотите сортировать ваши данные, то вам лучше сначала перейти от объекта к массиву, а уже потом выполнять сортировку, используя Array.prototype.sort. Это можно сделать, например, так:

var data = {
    'params': [
        {
            'name': 'last_name',
            'property_xxc': 'abcd',
            'sort_index': 2
        },
        {
            'name': 'name',
            'property_erw': 'abcd',
            'sort_index': 5
        },
        {
            'name': 'date',
            'property_xxc': 'abcd',
            'sort_index': 3
        }
    ]
}
data.params.sort(function(a, b) {
    return a.sort_index - b.sort_index;
});
console.dir(data);
READ ALSO
Функция для записи данных в массив

Функция для записи данных в массив

Столкнулся с такой проблемойУ меня есть функция (для вопроса упростил ее очень сильно):

196
Как правильно прочитать данный код var args = Array.prototype.slice.call(arguments); [дубликат]

Как правильно прочитать данный код var args = Array.prototype.slice.call(arguments); [дубликат]

Не могу связать воедино разрозненные (возможно поверхностные знания), помогите пожалуйста!

182
Общий JS в 2ух компонентах Vue.js подменяет template и style

Общий JS в 2ух компонентах Vue.js подменяет template и style

У меня есть 2 слайдера, которые отличаются друг от друга template и style, а script у обоих одинаковыйЯ вынес js в отдельный файл и подключаю через src

194