JS, хеши и цифровые ключи
JS сортирует хеш (объект) по ключам. А более подробно - хранит значения в хеше с цифровыми ключами от меньшего к большему ключу, как-будто это массив.
При этом цифровые ключи хранятся в начале хеша, а уже потом строковые - то есть, если вставить 10 чисел, потом строку, а потом опять 10 чисел, то получится в начале 20 чисел, а в конце строковый ключ.
То есть, нельзя быть уверенным, что ваш скрипт не заглючит, если вдруг вам важен порядок выборки значений, и если у вас вдруг оказались числовые ключи.
Пример:
Имеем массив (код условный для простоты, то есть главное в массиве - ключи начинаются не от нуля, ну или идут с промежутками):
s = [ 300 : 777, 200 : 333, 400 : 555 ];
Нам нужно его отсортировать по значениям, чтобы ключи сохранились.
Должно стать так, то есть, от большего к меньшему:
s = [ 200 : 333, 400 : 555, 300 : 777 ];
Стандартная .sort делает так (да даже и без стандартной sort при выборке значений из массива они будут идти от меньшего к большему, как бы мы их туда не добавляли - это и правильно):
s = [ 200 : 333, 300 : 777, 400 : 555 ];
Тут бага нет, массивы работают правильно.
Тогда пробуем получить объект (хеш):
function asort(arr, sort_function) { var i; if (sort_function == undefined) { sort_function = function(a, b) { return a - b } } var b = []; for (i in arr) { b.push([i, arr[i]]); } b.sort(function(a, b) { return sort_function(a[1], b[1]) }); var c = {}, len = b.length; for (i=0; i < len; i++) { c[b[i][0]] = b[i][1]; } return c; }
Обратите внимание на var c = {}, то есть, у нас именно хеш.
Но даже в этом хеше значения при их выборке по IN будут идти от меньшего к большему, а не в таком порядке, в каком мы их добавили!!!
Фиг знает, что это такое. Просто я нашёл эту и подобные функции в инете, тот же phpjs asort() также глючит!
По сути, попробовал, срабатывает превращение ключей в текстовые с добавлением, например, минуса перед числом (просто превращение в строку не срабатывает, видимо, внутри сильно оптимизировано):
c[('-'+b[i][0])] = b[i][1];
Тогда ключи идут в том порядке, в котором мы их добавили, то есть, как бы массив будет отсортирован по значениям, только это уже будет хеш.
Конечно, придётся учитывать при дальнейшей выборке этот минус. Ну или пробел использовать, а при выборке использовать parseInt для получения числа.
=====================
Ещё один вариант сортировки, без хешей:
Используем обычный массив, со значениями в виде хеша вида {"index": index, "val" : val}, где index - ключ, val - значение.
Сортируем по val с помощью .sort(func(a, b) {return b.val-a.val})
Получаем отсортированный массив с сохранившимися связями ключ->значение, правда, доступ медленнее по ключу.
Но в каждом случае можно выбрать нужный вариант.