Сортировка массива объектов в Chrome

Править: Как отмечено kennytm ниже и после исследования меня, согласно спецификации ECMA, когда два объекта полны решимости быть равными по пользовательскому виду, JavaScript не требуется, чтобы оставлять те два объекта в том же порядке. И Chrome и Opera являются только двумя главными браузерами, чтобы принять решение иметь нестабильные виды, но другие включают Netscape 8&9, Kazehakaze, IceApe и немногие другие. Команда Хрома отметила эту ошибку как "Работающий, как предназначено", таким образом, она не будет "зафиксирована". При необходимости в массивах для пребывания в их первоначальном заказе, когда значения будут равны, необходимо будет использовать некоторый дополнительный механизм (такой как тот выше). Возврат 0 когда сортировка объектов эффективно бессмысленна, не, беспокоятся - также. Или пользуйтесь библиотекой, которая поддерживает стабильный вид, такой как Underscore/Lodash.


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

Во всех других браузерах при сортировке массива объектов если два объекта решают к тому же значению, оставлен без изменений их порядок в обновленном массиве. В Chrome по-видимому рандомизируется их порядок. Выполните код ниже в Chrome и любом другом браузере, который Вы хотите. Необходимо видеть то, что я имею в виду.

У меня есть два вопроса:

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

Во-вторых, есть ли какой-либо хороший способ зафиксировать это? Единственная вещь, о которой я могу думать, добавляет число автопостепенного увеличения как атрибут каждому члену массива перед сортировкой и затем использованием того значения когда два объекта sort сравнивает твердость с тем же значением. Другими словами, никогда не возвращайтесь 0.

Вот пример кода:

var x = [
{'a':2,'b':1},
{'a':1,'b':2},
{'a':1,'b':3},
{'a':1,'b':4},
{'a':1,'b':5},
{'a':1,'b':6},
{'a':0,'b':7},
]

var customSort = function(a,b) {
    if (a.a === b.a) return 0;
    if (a.a > b.a) return 1;
    return -1;
};

console.log("before sorting");
for (var i = 0; i < x.length; i++) {
    console.log(x[i].b);
}
x.sort(customSort);

console.log("after sorting");
for (var i = 0; i < x.length; i++) {
    console.log(x[i].b);
}

Во всех других браузерах, что я вижу, то, что только первый участник и последний член массива перемещены (я вижу 7,2,3,4,5,6,1) но в Chrome по-видимому рандомизируются внутренние числа.

[РЕДАКТИРОВАНИЕ] Искренне благодарит Вас всем, кто ответил. Я предполагаю, что 'непоследовательный' не делает необходимый средний, это - ошибка. Кроме того, я просто хотел указать что мой b свойство было просто примером. На самом деле я сортирую некоторые относительно широкие объекты на любом приблизительно из 20 ключей согласно вводу данных пользователем. Даже отслеживание того, что пользователь, в последний раз отсортированный по все еще, не решит проблему случайности, которую я вижу. Мое обходное решение, вероятно, будет близким изменением этого (новый код выделяется):

var x = [
{'a':2,'b':1},
{'a':1,'b':2},
{'a':1,'b':3},
{'a':1,'b':4},
{'a':1,'b':5},
{'a':1,'b':6},
{'a':0,'b':7},
];
var i;

var customSort = function(a,b) {
    if (a.a === b.a) return a.customSortKey > b.customSortKey ? 1 : -1; /*NEW CODE*/
    if (a.a > b.a) return 1;
    return -1;
};

console.log("before sorting");
for (i = 0; i < x.length; i++) {console.log(x[i].b);}

for (i = 0; i < x.length; i++) {                      /*NEW CODE*/
    x[i].customSortKey = i;                           /*NEW CODE*/
}                                                     /*NEW CODE*/
x.sort(customSort);

console.log("after sorting");
for (i = 0; i < x.length; i++) {console.log(x[i].b);}

21
задан Andrew 27 May 2015 в 08:34
поделиться

3 ответа

Сорт V8, к сожалению, не стабилен. Попробую откопать ошибку в Хроме по этому поводу.

Сортировка V8 теперь стабильна!

8
ответ дан 29 November 2019 в 20:47
поделиться

Стандарт ECMAScript не гарантирует, что Array.sort является стабильной сортировкой . Chrome (движок V8) использует внутреннюю на месте QuickSort (для массивов размером ≥ 22, иначе сортировка вставкой), которая работает быстро, но нестабильно .

Чтобы исправить это, сравните customSort с .b , исключив необходимость стабильности алгоритма сортировки.

22
ответ дан 29 November 2019 в 20:47
поделиться

Возможно, вы это уже знаете, но вы можете использовать массив для сортировки по нескольким столбцам и избежать этой ошибки:

var customSort = function(a,b) {
    return [a.a, a.b] > [b.a, b.b] ? 1:-1;
}
8
ответ дан 29 November 2019 в 20:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: