Как отсортировать массив объектов в js
Мне нужно отсортировать массив объектов в js по массиву имен свойств, который передается в функцию. Вот к примеру
function sorting(obj, propName){
}
initial = [
{a : 1, b : "abc"},
{a : 2, b : "def"},
]
sorting(initial, ["a"]); //1
sorting(initial, ["b", "a"]); //2
В первом случае объекты в массиве initial должны быть отсортированы по свойству 'a', а во втором первично по свойству 'b' и вторично по свойству 'a'(т.е лексеграфически). Сортировка должна идти по возрастанию и быть устойчивой. Как это сдедлать?
Ответы (1 шт):
Можно написать компаратор, которые сперва сравнивает два объекта по нулевому свойству из массива propName, если данное свойство одинаково у двух объектов, то по следующему свойству из массива propName, и т.д.
Так как спецификация языка не требует, чтобы метод sort использовал устойчивую сортировку (1), то необходимо самостоятельно позаботиться об обеспечении устойчивости сортировки. Например, можно сортировать не исходный массив, а массив пар [элемент_исходного_массива, индекс_в_исходном_массиве]. Если два объекта равны по всем интересующим нас свойствам, то сравниваем индексы объектов.
function sorting(objArr, propName)
{
for (let i = 0; i < objArr.length; ++i)
objArr[i] = [objArr[i], i];
function comparator(a, b)
{
for (let prop of propName)
{
if (a[0][prop] < b[0][prop])
return -1;
else if (a[0][prop] > b[0][prop])
return 1;
}
return a[1] - b[1];
}
objArr.sort(comparator);
for (let i = 0; i < objArr.length; ++i)
objArr[i] = objArr[i][0];
}
let initial = [
{a : 2, b : "def", c: 7},
{a : 3, b : "def", c: 6},
{a : 1, b : "def", c: 5},
{a : 1, b : "def", c: 4},
{a : 3, b : "abc", c: 3},
{a : 2, b : "abe", c: 2},
{a : 2, b : "abd", c: 1},
{a : 2, b : "abc", c: 0},
];
console.log(1);
sorting(initial, ["a"]); //1
for (let obj of initial)
console.log(JSON.stringify(obj));
console.log(2);
sorting(initial, ["b", "a"]); //2
for (let obj of initial)
console.log(JSON.stringify(obj));
(1):
В ECMA-262, 9th edition, June 2018 говорится следующее (Array.prototype.sort):
The elements of this array are sorted. The sort is not necessarily stable (that is, elements that compare equal do not necessarily remain in their original order).
Но начиная с ECMA-262, 10th edition, June 2019 сортировка должна быть стабильной (Array.prototype.sort):
The elements of this array are sorted. The sort must be stable (that is, elements that compare equal must remain in their original order).