Obiekty vs tablice w Javascript dla par klucz / wartość

Powiedzmy, że masz bardzo prostą strukturę danych:

(personId, name)

...i chcesz zapisać kilka z nich w zmiennej javascript. Jak widzę masz trzy opcje:

// a single object
var people = {
    1 : 'Joe',
    3 : 'Sam',
    8 : 'Eve'
};

// or, an array of objects
var people = [
    { id: 1, name: 'Joe'},
    { id: 3, name: 'Sam'},
    { id: 8, name: 'Eve'}
];

// or, a combination of the two
var people = {
    1 : { id: 1, name: 'Joe'},
    3 : { id: 3, name: 'Sam'},
    8 : { id: 8, name: 'Eve'}
};

Druga lub trzecia opcja jest oczywiście droga, jeśli masz (lub spodziewasz się, że możesz mieć) więcej niż jedną "wartość" część do przechowywania (np, dodając w ich wieku lub coś), więc, dla dobra argumentacji, Załóżmy, że nigdy nie będzie więcej wartości danych potrzebnych w tej strukturze. Które jeden wybrać i dlaczego?


Edit: przykład pokazuje teraz najczęściej spotykaną sytuację: identyfikatory nie-sekwencyjne.

Author: nickf, 2009-03-27

6 answers

Każde rozwiązanie ma swoje zastosowania.

Myślę, że pierwsze rozwiązanie jest dobre, jeśli próbujesz zdefiniować relację jeden do jednego( np. proste mapowanie), zwłaszcza jeśli musisz użyć klucza jako klucza wyszukiwania.

Drugie rozwiązanie wydaje mi się najbardziej wytrzymałe w ogóle i prawdopodobnie użyłbym go, gdybym nie potrzebował szybkiego klucza wyszukiwania:

    To samo się opisuje, więc nie muszą polegać na każdym używającym ludzie aby wiedzieć, że kluczem jest identyfikator użytkownik.
  • każdy obiekt jest samowystarczalny, co jest lepsze do przekazywania danych gdzie indziej-zamiast dwóch parametrów (id i imię) po prostu mijasz osób.
  • To rzadki problem, ale czasami wartości klucza mogą nie być ważne dla Użyj jako kluczy. Na przykład kiedyś wanted to map string conversions (np.": "do">"), ale od ":" nie jest poprawna nazwa zmiennej musiałem użyj drugiej metody. Jest łatwo rozszerzalny, w przypadku gdzieś po drodze musisz dodaj więcej danych do niektórych (lub wszystkich) użytkowników. (Przepraszam, wiem o Twoim " dla argumentacja " ale to jest ważny aspekt.)

Trzeci byłby dobry, jeśli potrzebujesz szybkiego czasu wyszukiwania + niektóre z zalet wymienionych powyżej (przekazywanie danych, samoopisanie). Jeśli jednak nie potrzebujesz szybkiego czasu Wyszukiwania, jest to o wiele bardziej uciążliwe. Ponadto, tak czy inaczej, istnieje ryzyko błędu, jeśli id w obiekcie w jakiś sposób różni się od id w ludzie .

 56
Author: Daniel Lew,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-27 01:04:34

Właściwie, jest czwarta opcja:

var people = ['Joe', 'Sam', 'Eve'];

Ponieważ twoje wartości są następujące po sobie. (Oczywiście musisz dodać / odjąć jeden - - - lub po prostu umieścić undefined jako pierwszy element).

Osobiście wybrałbym Twoje (1) lub (3) , ponieważ te będą najszybsze do wyszukania kogoś po ID (o log n w najgorszym wypadku). Jeśli musisz znaleźć id 3 w (2), możesz albo wyszukać go według indeksu (w takim przypadku my (4) jest w porządku), albo musisz wyszukać - O(n).

Wyjaśnienie: mówię O (logN) jest najgorszym, jaki może być, ponieważ AFAIK i implementacja mogą zdecydować się na użycie zbalansowanego drzewa zamiast tabeli hash. Tabela hash będzie o (1), zakładając Minimalne kolizje.

Edit z nickf: od tego czasu zmieniłem przykład w OP, więc ta odpowiedź może już nie mieć większego sensu. Przepraszam.

Post-edit

Ok, post-edit, wybrałbym opcję (3). Jest rozszerzalny (łatwo dodawać nowe atrybuty), oferuje szybkie wyszukiwanie i może być iterowane również. Umożliwia również przejście od wpisu z powrotem do identyfikatora, jeśli zajdzie taka potrzeba.

Opcja (1) byłaby przydatna, jeśli (a) musisz zapisać pamięć; (b) nigdy nie musisz przechodzić z obiektu z powrotem do id; (c) nigdy nie rozszerzysz przechowywanych danych (np. nie możesz dodać nazwiska osoby)

Opcja (2) jest dobra, jeśli (a) trzeba zachować kolejność; (b) trzeba iterację wszystkich elementów; (c) nie trzeba szukać elementów według id, chyba że jest posortowane według id (można zrobić wyszukiwanie binarne w O (log n ). Zauważ oczywiście, że jeśli musisz to uporządkować, to zapłacisz za insert.

 7
Author: derobert,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-27 02:57:36

Zakładając, że dane nigdy się nie zmienią, pierwsza (pojedynczy obiekt) opcja jest najlepsza.

Prostota struktury oznacza, że jest ona najszybsza do przetworzenia, a w przypadku małych, rzadko (lub nigdy) zmieniających się zestawów danych, takich jak ten, mogę sobie tylko wyobrazić, że będzie ona często wykonywana - w takim przypadku minimalny narzut jest drogą.

 2
Author: karim79,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-27 01:06:03

Stworzyłem małą bibliotekę do zarządzania kluczowymi parami wartości.

Https://github.com/scaraveos/keyval.js#readme

Używa

  • obiekt do przechowywania kluczy, który pozwala na szybkie usuwanie i pobieranie wartości operacje i
  • lista linkowana pozwalająca na bardzo szybką iterację wartości

Mam nadzieję, że pomoże:)

 2
Author: scaraveos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-03 11:06:40

Trzecia opcja jest najlepsza dla każdej przyszłościowej aplikacji. Prawdopodobnie będziesz chciał dodać więcej pól do rekordu osoby, więc pierwsza opcja jest nieodpowiednia. Ponadto, jest bardzo prawdopodobne, że będziesz miał dużą liczbę osób do przechowywania i będziesz chciał szybko wyszukać rekordy - dlatego wrzucanie ich do prostej tablicy (jak to ma miejsce w opcji #2) też nie jest dobrym pomysłem.

Trzeci wzorzec daje możliwość użycia dowolnego ciągu znaków jako ID, ma złożone struktury Person I zdobądź i ustaw rekordy osoby w stałym czasie. Zdecydowanie tak trzeba.

Jedną z rzeczy, której brakuje w opcji # 3, jest stabilna deterministyczna kolejność (co jest zaletą opcji # 2). Jeśli potrzebujesz tego, zalecam zachowanie uporządkowanej tablicy identyfikatorów osób jako oddzielnej struktury, gdy musisz wymienić osoby w kolejności. Zaletą byłoby to, że można zachować wiele takich tablic, dla różnych porządków tego samego zestawu danych.

 1
Author: levik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-27 02:37:21

Biorąc pod uwagę twoje ograniczenie, że zawsze będziesz miał tylko nazwę jako wartość, wybrałbym pierwszą opcję. Jest najczystsza, ma najmniej nad głową i najszybsze spojrzenie w górę.

 0
Author: Nathaniel Reinhart,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-27 01:15:44