Jak tworzyć słownik i dynamicznie dodawać pary klucz-wartość?

323

Z postu:

Wysyłanie tablicy JSON do odebrania jako Słownik <ciąg, ciąg>

Próbuję zrobić to samo co ten post. Jedynym problemem jest to, że nie wiem, jakie klucze i wartości są z góry. Muszę więc być w stanie dynamicznie dodawać pary klucz i wartość i nie wiem, jak to zrobić.

Czy ktoś wie, jak stworzyć ten obiekt i dynamicznie dodawać pary kluczowych wartości?

Próbowałem:

var vars = [{key:"key", value:"value"}];
vars[0].key = "newkey";
vars[0].value = "newvalue";

Ale to nie działa.

KenEucker
źródło
2
Działa świetnie. console.log (vars); pokaż mi [Klucz obiektu: wartość „newkey” : proto „nowa wartość” : Obiekt]
Alex Pliutau
Poza tym jest to lista, a nie słownik: \ Myślę, że dane są lepiej reprezentowane jako lista "par", jak list = [["key1","value1"],["key2","value2"]]. Niektóre inne języki mają typ „pary” lub „krotki”. tldr do faktycznego dodania:dict['key'] = "value"
Jordan Stewart

Odpowiedzi:

551
var dict = []; // create an empty array

dict.push({
    key:   "keyName",
    value: "the value"
});
// repeat this last part as needed to add more key/value pairs

Zasadniczo tworzysz literał obiektu z 2 właściwościami (nazywanymi keyi value) i wstawiasz go (za pomocą push()) do tablicy.


Edycja: A więc prawie 5 lat później ta odpowiedź jest negatywna, ponieważ nie tworzy „normalnego” dosłownego obiektu JS (aka map, aka hash, aka słownik).
To jest jednak tworząc strukturę PO zażądano (i które są zilustrowane w innych kwestii związanych z), która jest tablicą literałach obiektów , z których każdy key, a valuewłaściwości. Nie pytaj mnie, dlaczego ta struktura była wymagana, ale o tę poproszono.

Ale, ale jeśli chcesz tego w prostym obiekcie JS - a nie o strukturę, o którą prosi OP - zobacz odpowiedź tcll , chociaż notacja w nawiasach jest nieco kłopotliwa, jeśli masz tylko proste klucze, które są prawidłowymi nazwami JS. Możesz po prostu to zrobić:

// object literal with properties
var dict = {
  key1: "value1",
  key2: "value2"
  // etc.
};

Lub użyj zwykłej notacji kropkowej, aby ustawić właściwości po utworzeniu obiektu:

// empty object literal with properties added afterward
var dict = {};
dict.key1 = "value1";
dict.key2 = "value2";
// etc.

Ty nie chcesz notacji nawiasu jeśli masz klucze, które mają spacje w nich znaki specjalne lub takie rzeczy. Na przykład:

var dict = {};

// this obviously won't work
dict.some invalid key (for multiple reasons) = "value1";

// but this will
dict["some invalid key (for multiple reasons)"] = "value1";

Chcesz także notacji nawiasowej, jeśli twoje klucze są dynamiczne:

dict[firstName + " " + lastName] = "some value";

Zauważ, że klucze (nazwy właściwości) są zawsze ciągami, a wartości nie łańcuchowe będą wymuszone na łańcuch, gdy zostaną użyte jako klucz. Np. DateObiekt zostaje przekonwertowany na jego reprezentację ciągu:

dict[new Date] = "today's value";

console.log(dict);
// => {
//      "Sat Nov 04 2016 16:15:31 GMT-0700 (PDT)": "today's value"
//    }

Zauważ jednak, że to niekoniecznie „po prostu działa”, ponieważ wiele obiektów będzie miało ciąg znaków, "[object Object]"co nie oznacza, że ​​nie jest unikalny klucz. Uważaj więc na coś takiego:

var objA = { a: 23 },
    objB = { b: 42 };

dict[objA] = "value for objA";
dict[objB] = "value for objB";

console.log(dict);
// => { "[object Object]": "value for objB" }

Mimo objAi objBbędąc całkowicie różnych i unikalnych elementów, oba mają taką samą podstawową reprezentację ciąg: "[object Object]".

Powodem Datetego nie jest to, że Dateprototyp ma niestandardową toStringmetodę, która zastępuje domyślną reprezentację ciągu. Możesz zrobić to samo:

// a simple constructor with a toString prototypal method
function Foo() {
  this.myRandomNumber = Math.random() * 1000 | 0;
}

Foo.prototype.toString = function () {
  return "Foo instance #" + this.myRandomNumber;
};

dict[new Foo] = "some value";

console.log(dict);
// => {
//      "Foo instance #712": "some value"
//    }

(Należy zauważyć, że ponieważ powyższe używa liczb losowych , kolizje nazw mogą nadal występować bardzo łatwo. To tylko ilustruje implementację toString.)

Dlatego podczas próby użycia obiektów jako kluczy JS użyje własnej toStringimplementacji obiektu, jeśli istnieje, lub użyje domyślnej reprezentacji ciągu.

Flambino
źródło
2
Czy to jest asocjacyjne?
Csaba Toth,
1
@CsabaToth Nie, dictnie jest słownikiem asocjacyjnym. Jest to tablica obiektów, z których każdy jest trochę jak słownik z dwoma kluczami: „klucz” i „wartość”.
Roman Starkov,
1
To, co tam masz, to tablica, która jest jedynie nazwana „dict”.
Jan Kyu Peblik,
2
Doceń aktualizację i śledź dodatkowe informacje.
Jakub
410
var dict = {};

dict['key'] = "testing";

console.log(dict);

działa jak python :)

wyjście konsoli:

Object {key: "testing"} 
Tcll
źródło
3
Jest to z pewnością najlepsze podejście do budowy słownika i JEST poprawną odpowiedzią!
Rzym.
3
Bardzo ważne, aby inicjalizować je w nawiasach {}zamiast w nawiasach
Jaider,
Używam również podstawowych obiektów jako takich słowników. Cieszę się, że to właściwa droga!
TKoL
5
„Piękno” javascript! Obiekt JEST w rzeczywistości sam słownik par klucz-wartość
100r
1
@Azurespot kluczem może być dowolny skrót, klucze są uporządkowane według skrótów, które w Python3 różnią się każdym uruchomieniem.
Tcll,
54

To tak proste, jak:

var blah = {}; // make a new dictionary (empty)

lub

var blah = {key: value, key2: value2}; // make a new dictionary with two pairs 

następnie

blah.key3 = value3; // add a new key/value pair
blah.key2; // returns value2
blah['key2']; // also returns value2
Simon Sarris
źródło
1
@ KenEucker Myślę, że przy takich pytaniach przydatne są złe odpowiedzi. Zwłaszcza jeśli ktoś wyjaśni, dlaczego się mylą, jest to dobry zasób do nauki.
CJBrew
32

Ponieważ oświadczyłeś, że chcesz obiekt słownika (a nie tablicę, jak zakładam, niektórzy rozumieją), myślę, że właśnie o to ci chodzi:

var input = [{key:"key1", value:"value1"},{key:"key2", value:"value2"}];

var result = {};

for(var i = 0; i < input.length; i++)
{
    result[input[i].key] = input[i].value;
}

console.log(result); // Just for testing
ZenMaster
źródło
Inne rozwiązanie wykorzystujące .push do tablicy działa na moje potrzeby, ale zakładam, że to też zadziałałoby, gdybym spróbował.
KenEucker,
2
O ile nie zrozumiem, czym jest obiekt Dictionary, twoje pytanie jest wtedy mylące. Jak uzyskasz wartość według klucza z tablicy?
ZenMaster
Korzystam z JSON.stringify na tym obiekcie, a następnie łapię go za pomocą kontrolera w MVC 3. Jest to tak, że jest on odpowiednio sformatowany przed utworzeniem łańcucha i wysłaniem go dalej.
KenEucker,
23

JavaScript Object jest sam w sobie jak słownik. Nie trzeba wymyślać koła na nowo.

var dict = {};

// Adding key-value -pairs
dict['key'] = 'value'; // Through indexer
dict.anotherKey = 'anotherValue'; // Through assignment

// Looping through
for (var item in dict) {
  console.log('key:' + item + ' value:' + dict[item]);
  // Output
  // key:key value:value
  // key:anotherKey value:anotherValue
}

// Non existent key
console.log(dict.notExist); // undefined

// Contains key?
if (dict.hasOwnProperty('key')) {
  // Remove item
  delete dict.key;
}

// Looping through
for (var item in dict) {
  console.log('key:' + item + ' value:' + dict[item]);
  // Output
  // key:anotherKey value:anotherValue
}

Skrzypce

Jani Hyytiäinen
źródło
11

Możesz używać map z Map:

var sayings = new Map();
sayings.set('dog', 'woof');
sayings.set('cat', 'meow');
Preetham Kumar P.
źródło
9

Zdarzyło mi się przejść przez to pytanie w poszukiwaniu czegoś podobnego. Dało mi to wystarczającą ilość informacji, aby przeprowadzić test, aby uzyskać odpowiedź, której chciałem. Jeśli więc ktoś inny chce wiedzieć, jak dynamicznie dodawać lub wyszukiwać parę {klucz: „wartość”} w obiekcie JavaScript, ten test powinien powiedzieć ci wszystko, co możesz wiedzieć.

var dictionary = {initialkey: 'initialValue'};
var key = 'something';
var key2 =  'somethingElse';
var value = 'value1';
var value2 = 'value2';
var keyInitial = 'initialkey';

console.log(dictionary[keyInitial]);

dictionary[key] =value;
dictionary[key2] = value2;
console.log(dictionary);

wynik

initialValue
{ initialkey: 'initialValue',
  something: 'value1',
  somethingElse: 'value2' }
użytkownik2301449
źródło
2
To nie jest pytanie. Zamiast tego powinieneś zadać pytanie, a następnie sam na nie odpowiedzieć. Byłoby to znacznie łatwiejsze do zrozumienia i zorganizowania.
SalmonKiller
1
dzięki @SalmonKiller Nie byłem pewien właściwej terminologii, aby napisać własne pytanie i oczekiwać, że zostanie zrozumiane, ale w trakcie moich poszukiwań zdarzyło mi się to, że wszystkie informacje tam były, ale rozdzieliłem się między kilkoma odpowiedziami, więc odpowiedziałem na koncepcję tego pytania w sposób, który odpowiedziałby na to pytanie dla kogoś, kto natknął się na to pytanie, szukając tego samego, co ja
user2301449
1
LOL. Przeglądałem to i wyglądało to jak pytanie zamiast odpowiedzi. Przepraszam stary!
SalmonKiller
Dziękujemy za dodanie tego. Możesz również umieścić go w skrzypcach, jak w powyższej odpowiedzi.
KenEucker
8
var dictionary = {};//create new object
dictionary["key1"] = value1;//set key1
var key1 = dictionary["key1"];//get key1
SharpCoder
źródło
w celu zwiększenia wydajności powinieneś odwoływać się key1 = dictionary.key1zamiast indeksowaćkey1 = dictionary["key1"]
Tcll
4

Możesz utworzyć Słownik klasowy, aby łatwo wchodzić w interakcje z listą Słownik:

class Dictionary {
  constructor() {
    this.items = {};
  }
  has(key) {
    return key in this.items;
  }
  set(key,value) {
    this.items[key] = value;
  }
  delete(key) {
    if( this.has(key) ){
      delete this.items[key]
      return true;
    }
    return false;
  }
}

var d = new Dictionary();
d.set(1, "value1")
d.set(2, "value2")
d.set(3, "value3")
console.log(d.has(2));
d.delete(2);
console.log(d.has(2));

agonza1
źródło
3

co powiesz na jedną linijkę do tworzenia pary klucz-wartość?

let result = { ["foo"]: "some value" };

a niektóre funkcje iteratora, takie jak reducedynamiczna konwersja tablicy do słownika

var options = [
  { key: "foo", value: 1 },
  { key: "bar", value: {id: 2, name: "two"} },
  { key: "baz", value: {["active"]: true} },
];

var result = options.reduce((accumulator, current) => {
  accumulator[current.key] = current.value;
  return accumulator;
}, {});

console.log(result);

Dan Dohotaru
źródło
3

We współczesnym javascript (ES6 / ES2015) należy używać struktury danych mapy dla słownika. Struktura danych mapy w ES6 pozwala używać dowolnych wartości jako kluczy.

const map = new Map();
map.set("true", 1);
map.set("false", 0);

Jeśli nadal używasz ES5, poprawnym sposobem na utworzenie słownika jest utworzenie obiektu bez prototypu w następujący sposób.

var map = Object.create(null);
map["true"]= 1;
map["false"]= 0;

Istnieje wiele zalet tworzenia słownika bez obiektu prototypowego. Poniżej blogi warto przeczytać na ten temat.

wzór dykt

obiekty jako mapy

Jyoti Prasad Pal
źródło
2

Pomogłoby to tonie dowiedzieć się, jaki jest twój końcowy pożądany rezultat, ale myślę, że tego właśnie chcesz:

var vars = [{key:"key", value:"value"}];

vars.push({key: "newkey", value: "newvalue"})
gddc
źródło
2

Natrafiłem na ten problem .. ale w pętli for. Najważniejsze rozwiązanie nie działało (podczas używania zmiennych (a nie ciągów) dla parametrów funkcji push), a inne nie uwzględniały kluczowych wartości opartych na zmiennych. Byłem zaskoczony, że to podejście (które jest powszechne w php) zadziałało.

  // example dict/json                  
  var iterateDict = {'record_identifier': {'content':'Some content','title':'Title of my Record'},
    'record_identifier_2': {'content':'Some  different content','title':'Title of my another Record'} };

  var array = [];

  // key to reduce the 'record' to
  var reduceKey = 'title';

  for(key in iterateDict)
   // ultra-safe variable checking...
   if(iterateDict[key] !== undefined && iterateDict[key][reduceKey] !== undefined)
    // build element to new array key
     array[key]=iterateDict[key][reduceKey];
redcap3000
źródło
1

Ulepszeniem var dict = {}jest użycie var dict = Object.create(null).

Spowoduje to utworzenie pustego obiektu, którego nie ma Object.prototypejako prototypu.

var dict1 = {};
if (dict1["toString"]){
    console.log("Hey, I didn't put that there!")
}
var dict2 = Object.create(null);
if (dict2["toString"]){
    console.log("This line won't run :)")
}
WoodenKitty
źródło
1

Pierwsza inicjalizacja tablicy globalnie

var dict = []

Dodaj obiekt do słownika

dict.push(
     { key: "One",value: false},
     { key: "Two",value: false},
     { key: "Three",value: false});

Output : 
   [0: {key: "One", value: false}
    1: {key: "Two", value: false}
    2: {key: "Three", value: false}]

Zaktualizuj obiekt ze słownika

Object.keys(dict).map((index) => {        
  if (index == 1){
    dict[index].value = true
  }
});

Output : 
   [0: {key: "One", value: false},
    1: {key: "Two", value: true},
    2: {key: "Three", value: false}]

Usuń obiekt ze słownika

Object.keys(dict).map((index) => {              
      if (index == 2){
        dict.splice(index)
      }
    });

Output : 
    [0: {key: "One", value: false},
     1: {key: "Two", value: true}]
Pratik Panchal
źródło