Jak udržet uspořádaný objekt/pole Javascriptu a zároveň zachovat vyhledávání klíčů?

Mám některá data, která jsem původně uložil do obecného objektu Javascript, s ID jako klíčem:

{
  "7": {"id":"7","name":"Hello"},
  "3": {"id":"3","name":"World"},
  ...
}

Zjistil jsem však, že prohlížeče nezaručují konkrétní pořadí objektů, když je procházejí, takže ve výše uvedeném by „3“ bylo před „7“. Přešel jsem na použití formátu pole, jako je tento:

[
  {"id":"7","name":"Hello"},
  {"id":"3","name":"World"},
  ...
]

Nyní mohu smyčku ve správném pořadí, ale nemohu provádět rychlé vyhledávání, např. data["3"] aniž byste museli procházet polem.

Existuje dobrý způsob, jak oba přístupy zkombinovat? Raději bych se vyhnul použití samostatného objektu pro každý formát, protože objekt je dost velký (stovky prvků).

Odpověď

S tímto problémem jsem se také setkal. Řešením je ponechat uspořádané pole klíčů navíc k původnímu objektu.

var objects = {
  "7": {"id":"7","name":"Hello"},
  "3": {"id":"3","name":"World"},
  ...
}
var order = [ "3", "7", ... ];

Nyní, pokud chcete druhý prvek, můžete provést toto vyhledávání:

var second_object = objects[order[1]];

Standard ECMA neříká nic o pořadí prvků v objektu. A konkrétně Chrome mění pořadí kláves, když vypadají čísla.Příklad:

var example = {
    "a": "a",
    "b": "b",
    "1": "1",
    "2": "2"
};

pokud to vytisknete v Chrome, dostanete něco jako:

{
    1: "1",
    2: "2",
    "a": "a",
    "b": "b"
};

Je to trochu kyselé, ale život.

Můžete také použít řešení, které Andy propojil, v zásadě tyto dva zabalit do jednoho objektu.

Alternativou, kterou hojně využívám, je vlastní mapová funkce, která umožňuje určit pořadí, ve kterém se objektem prochází. Obvykle budete třídit, když tisknete data uživateli, takže zatímco budete opakovat a vytvářet řádky tabulky (například), váš iterátor bude řádky předávat v pořadí, které určuje funkce řazení. Myslel jsem, že je to dobrý nápad 🙂

Podpis vypadá takto:

function map(object, callback, sort_function);

Příklad použití:

map(object, function (row) {
   table.add_row(row.header, row.value);
}, function (key1, key2) {
   return object[key1] - object[key2];
});