Как предотвратить сортировку Object.keys ()? - PullRequest
0 голосов
/ 21 октября 2019

Проблема со стандартом ECMA для сортировки Object.keys() известна:
Object.keys() обрабатывает все ключи с целым числом (пример: 168), включая целое число как строки (пример: "168"), как целое число,В результате оба они одинаковы (168 === "168") и перезаписывают себя.

var object = {};
object["168"] = 'x';
object[168] = 'y';
Object.keys(object); // Array [ "168" ]
object[Object.keys(object)]; // "y"

Интересно, что все ключи (включая чистые целочисленные ключи) возвращаются в виде строки.
В ecma262 об этом написали: все ключи будут обрабатываться как целое число, ожидайте ключ is a String but is not an array index. https://tc39.es/ecma262/#sec-ordinaryownpropertykeys
Это должно сказать нам: 168 === "168". A toString() не решает проблему.

var object = {};
object[[3].toString()] = 'z';
object[[1].toString()] = 'x';
object[[2].toString()] = 'y';
Object.keys(object);
// Array(3) [ "1", "2", "3" ]

Как ни парадоксально, в этом случае только целое число применяется как «перечислимое» (игнорируется array.sort(), что также сортирует строки с буквами.).

Мой вопрос об этом прост: как я могу предотвратить функцию сортировки в Object.keys()? У меня есть тест Object.defineProperties(object, 1, {value: "a", enumerable: true/false}), но это означает, что не может быть действительно перечисляемым в случае целочисленной или строковой или целочисленной строки. Это означает, что только следует считать или нет. Это означает «подсчитано», как «пропустить» (если оно ложно), а не «подсчитано», как по возрастанию или по убыванию.

Подобный ответ не является хорошим ответом: используйте только буквы [a-zA-Z] илинаименьшая буква в первой позиции ключевого слова.

Что я хочу: чтобы ключи не сортировались, а выводились в порядке их ввода, будь то целое число, строка или символ.

Отказ от ответственности: пожалуйста, решения только в JavaScript.

1 Ответ

0 голосов
/ 21 октября 2019

Объекты Javascript неупорядочены по своей природе. Если вам нужна упорядоченная объектно-подобная переменная, я бы предложил использовать map .

. Чтобы достичь того, что вы ищете, с помощью карты вместо объекта, вы должны сделать что-то вроде ниже:

var map1 = new Map();
map1.set("123", "c");
map1.set(123, "b");
var iterator1 = map1.keys();
var myarray = [];
for (var i = 0; i < map1.size; i++) {
  myarray.push(iterator1.next().value);
}
console.log(myarray);
// Array ["123", 123]

К сожалению, он не совместим с IE, и я не уверен, как еще можно добиться того, что вам нужно без него. Быстрый Google все-таки возвратил что-то о картах jQuery .

Если вы не хотите использовать jQuery и все еще должны поддерживать IE, некоторые пункты приведены ниже:

Что-нибудь мешает вам использовать массив, а не объект JS для хранения нужных вам данных? Это сохранит порядок в соответствии с вашими требованиями в отличие от объектов. Вы можете иметь запись объекта в каждой итерации, которая представляет ключ, а затем использовать традиционный foreach для получения их в виде массива. Т.е.

Массив:

var test_array = [
    {key: 123,   value: 'a value here'},
    {key: "123", value: 'another value here'}
];
// console.log(test_array);

Получение ключей:

var test_array_keys = [];
test_array.forEach(function(obj) { test_array_keys.push(obj['key']); } );
// console.log(test_array_keys);

Затем, если вам нужно проверить, существует ли ключ, перед добавлением новой записи (чтобы предотвратитьдубликаты) вы можете сделать:

function key_exists(key, array)
{
    return array.indexOf(key) !== -1;
}

if(key_exists('12345', test_array_keys))
{
  // won't get here, this is just for example
    console.log('Key 12345 exists in array');
}
else if(key_exists('123', test_array_keys))
{
    console.log('Key 123 exists in array');
}

Будет ли это работать? Если нет, то единственным другим предложением будет сохранение отдельного массива рядом с объектом, который отслеживает ключи и обновляется при добавлении или удалении записи в / из объекта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...