Как вывести JSON без сортировки с сохранением ключей?

По API получаю данные в таком виде:

let ajax = '{"3":{"name":"test 3"},"1":{"name":"test 1"},"2":{"name":"test 2"}}';

Читал, что json автоматически сортируется, но мне нужно вывести в том порядке в котором получаю данные

test 3
test 1
test 2

Можно ли как то решить данный вопрос?

И самое важное сохранить ключи так как по ним идет обращение, в очень многих местах в таком виде data[searchId]

let data = {
 "3": {"name": "test 3"},
 "1": {"name": "test 1"},
 "2": {"name": "test 2"},
}

for (let i in data) {
   document.querySelector('.list').insertAdjacentHTML('beforeend', data[i].name +'<br>');
}

let searchId = "2";

console.log(data[searchId]);
<div class="list"></div>


Ответы (1 шт):

Автор решения: EzioMercer

Проблема в том, что в объекте числовые ключи хранятся в упорядоченном виде, потому чтобы ключ не был числовым, достаточно добавить какой-то префик к этому ключу и тогда ключи сохранят свой порядок

Заранее предупреждаю, что алгоритм написан исключительно для вашего случая - это значит, что в JSON-е в виде строки последовательность вида:

кавычки число кавычки двоеточие открывающаяФигурнаяСкобка

однозначно определяет ключ и начало его значения. Если где-то ещё, например имени ключа в подобъекте (там где name) или в значении свойства в подобъекте (там где "test число") встретится такая же последовательность или ещё где-то, то алгоритм работать не будет и приведёт к неожиданным результатам

Алгоритм:

  1. Добавлем префикс (пробел) к числовым ключам, чтобы они не меняли свой порядой при парсинге

    1.1 Во втором аргументе replaceAll знак $1 является десятичной цифрой, вставляет 1-ую сопоставившуюся подгруппу из объекта RegExp в первом параметре. Более подробно про такие символы можно прочитать тут

  2. Далее мы оборачиваем наш объект в Proxy, чтобы можно было кастомизировать полчуение значения по имени ключа (get). Это нам надо чтобы мы могли получить доступ к значению написав ключ как число и как пробел + число. Например в цикле for..in key будет выглядеть как пробел + число, а ниже при простом обращении мы просто пишем число

Код:

const ajax = '{"3":{"name":"test 3"},"1":{"name":"test 1"},"22":{"name":"test 22"}}';
const modifiedAjax = ajax.replaceAll(/"(\d+)":{/g, '" $1":{');

console.log(modifiedAjax);

const data = new Proxy(JSON.parse(modifiedAjax), {
  get(target, prop, receiver) {
    return prop[0] === ' ' ? target[prop] : target[' ' + prop];
  }
});

for (const key in data) {
  document.querySelector('.list').insertAdjacentHTML('beforeend', data[key].name +'<br>');
}

const searchId = "22";

console.log(data[searchId]);
<div class="list"></div>

→ Ссылка