Bagaimana cara membuat kamus dan menambahkan pasangan kunci-nilai secara dinamis?

324

Dari pos:

Mengirim array JSON untuk diterima sebagai Kamus <string, string>

Saya mencoba melakukan hal yang sama dengan posting itu. Satu-satunya masalah adalah bahwa saya tidak tahu apa kunci dan nilainya dimuka. Jadi saya harus bisa menambahkan pasangan kunci dan nilai secara dinamis dan saya tidak tahu bagaimana melakukannya.

Adakah yang tahu cara membuat objek itu dan menambahkan pasangan nilai kunci secara dinamis?

Saya sudah mencoba:

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

Tapi itu tidak berhasil.

KenEucker
sumber
2
Ini bekerja dengan baik. console.log (vars); tunjukkan [Kunci objek: nilai "kunci": "nilai baru" proto : Obyek]
Alex Pliutau
Kecuali untuk itu adalah daftar, bukan kamus: \ Saya pikir data lebih baik direpresentasikan sebagai daftar "pasangan" juga, seperti list = [["key1","value1"],["key2","value2"]]. Beberapa bahasa lain memiliki tipe "pair", atau "tuple". tldr untuk dict aktual menambahkan:dict['key'] = "value"
Jordan Stewart

Jawaban:

553
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

Pada dasarnya, Anda membuat objek literal dengan 2 properti (dipanggil keydan value) dan memasukkannya (menggunakan push()) ke dalam array.


Sunting: Jadi hampir 5 tahun kemudian, jawaban ini semakin menurun karena tidak membuat literal objek JS "normal" (alias peta, alias hash, alias kamus).
Hal ini namun menciptakan struktur yang OP meminta (dan yang diilustrasikan pada pertanyaan lain yang terhubung ke), yang merupakan array literal objek , masing-masing dengan keydan valuesifat. Jangan tanya saya mengapa struktur itu diperlukan, tapi itu yang diminta.

Tapi, tetapi, jika apa yang Anda inginkan dalam objek JS sederhana - dan bukan struktur yang diminta OP - lihat jawaban tcll , meskipun notasi braket sedikit rumit jika Anda hanya memiliki kunci sederhana yang merupakan nama JS yang valid. Anda bisa melakukan ini:

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

Atau gunakan notasi titik biasa untuk mengatur properti setelah membuat objek:

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

Anda tidak ingin notasi braket jika Anda punya kunci yang memiliki ruang di dalamnya, karakter khusus, atau hal-hal seperti itu. Misalnya:

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";

Anda juga ingin notasi braket jika kunci Anda dinamis:

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

Perhatikan bahwa kunci (nama properti) selalu berupa string, dan nilai non-string akan dipaksa ke string saat digunakan sebagai kunci. Misalnya Dateobjek dikonversi ke representasi stringnya:

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

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

Perhatikan bahwa ini tidak selalu "hanya berfungsi", karena banyak objek akan memiliki representasi string seperti "[object Object]"yang tidak membuat kunci non-unik. Jadi berhati-hatilah terhadap sesuatu seperti:

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" }

Meskipun objAdan objBmenjadi elemen yang sama sekali berbeda dan unik, mereka berdua memiliki representasi string dasar yang sama: "[object Object]".

Alasannya Datetidak berperilaku seperti ini adalah bahwa Dateprototipe memiliki toStringmetode kustom yang mengesampingkan representasi string default. Dan Anda dapat melakukan hal yang sama:

// 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"
//    }

(Perhatikan bahwa karena di atas menggunakan angka acak , tabrakan nama masih dapat terjadi dengan sangat mudah. ​​Hanya untuk menggambarkan implementasi dari toString.)

Jadi ketika mencoba menggunakan objek sebagai kunci, JS akan menggunakan toStringimplementasi objek itu sendiri , jika ada, atau menggunakan representasi string default.

Flambino
sumber
2
Apakah itu asosiatif?
Csaba Toth
1
@CsabaToth Tidak, dictbukan kamus asosiatif. Ini adalah array objek, yang masing-masing sedikit seperti kamus dengan dua tombol: "kunci" dan "nilai".
Roman Starkov
1
Apa yang Anda miliki di sana adalah array yang hanya bernama 'dict'.
Jan Kyu Peblik
2
Hargai pembaruan dan tindak lanjuti informasi tambahan.
Yakub
411
var dict = {};

dict['key'] = "testing";

console.log(dict);

bekerja seperti python :)

output konsol:

Object {key: "testing"} 
Tcll
sumber
3
Ini tentu saja merupakan pendekatan terbaik untuk membangun kamus, dan ADALAH jawaban yang benar!
Roman
3
Sangat penting untuk diinisialisasi dengan kurung {}daripada kurung
Jaider
Saya juga menggunakan objek dasar sebagai kamus seperti ini. Senang melihat itu cara yang benar!
TKoL
5
'Keindahan' javascript! Obyek sebenarnya adalah pasangan kunci nilai kamus itu sendiri
100r
1
@Azurespot kuncinya bisa berupa apa saja yang bisa hashable, bagaimanapun juga kunci diurutkan berdasarkan hash, yang dalam python3 berbeda setiap kali dijalankan.
Tcll
53

Sesederhana:

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

atau

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

kemudian

blah.key3 = value3; // add a new key/value pair
blah.key2; // returns value2
blah['key2']; // also returns value2
Simon Sarris
sumber
1
@ KenEucker Saya pikir bermanfaat untuk mendapatkan jawaban yang salah dalam pertanyaan seperti ini. Terutama jika seseorang menjelaskan mengapa mereka salah, itu adalah sumber belajar yang bagus.
CJBrew
32

Karena Anda telah menyatakan bahwa Anda menginginkan objek kamus (dan bukan array seperti yang saya asumsikan dipahami), saya pikir inilah yang Anda cari:

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
sumber
Solusi lain menggunakan .push menjadi sebuah array berfungsi untuk saya gunakan, tapi saya menganggap ini juga akan berfungsi jika saya mencobanya.
KenEucker
2
Kecuali jika saya salah memahami apa objek Kamus, pertanyaan Anda menyesatkan kemudian. Bagaimana Anda mengambil nilai dengan kunci dari array Anda?
ZenMaster
Saya menggunakan JSON.stringify pada objek ini dan kemudian menangkapnya dengan pengontrol di MVC 3. Ini hanya agar diformat dengan benar sebelum dirubah dan dikirim bersama.
KenEucker
23

JavaScript ini Object adalah dalam dirinya sendiri seperti kamus. Tidak perlu menemukan kembali roda.

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
}

Biola

Jani Hyytiäinen
sumber
11

Anda dapat menggunakan peta dengan Map, seperti ini:

var sayings = new Map();
sayings.set('dog', 'woof');
sayings.set('cat', 'meow');
Preetham Kumar P
sumber
9

Saya kebetulan berjalan di pertanyaan ini mencari sesuatu yang serupa. Itu memberi saya info yang cukup untuk menjalankan tes untuk mendapatkan jawaban yang saya inginkan. Jadi, jika ada orang lain yang ingin tahu cara menambahkan secara dinamis atau mencari pasangan {key: 'value'} dalam objek JavaScript, tes ini akan memberi tahu Anda semua yang mungkin perlu Anda ketahui.

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);

keluaran

initialValue
{ initialkey: 'initialValue',
  something: 'value1',
  somethingElse: 'value2' }
pengguna2301449
sumber
2
Ini bukan sebuah pertanyaan. Yang harus Anda lakukan adalah mengajukan pertanyaan dan kemudian jawab sendiri. Itu akan jauh lebih mudah untuk dipahami dan diatur.
SalmonKiller
1
terima kasih @SalmonKiller saya tidak yakin tentang terminologi yang tepat untuk menulis pertanyaan saya sendiri dan mengharapkannya dipahami tetapi kemudian saya menemukan ini dalam pencarian saya semua informasi ada di sana tetapi tersebar di antara beberapa jawaban jadi saya menjawab konsep pertanyaan ini dalam cara yang akan menjawabnya untuk orang lain yang tersandung ke pertanyaan ini mencari hal yang sama seperti saya
user2301449
1
LOL. Saya sedang meninjau ini dan itu tampak seperti pertanyaan, bukan jawaban. Maaf teman!
SalmonKiller
Terima kasih telah menambahkan ini. Anda juga bisa memasukkannya ke dalam biola seperti jawaban di atas.
KenEucker
8
var dictionary = {};//create new object
dictionary["key1"] = value1;//set key1
var key1 = dictionary["key1"];//get key1
SharpCoder
sumber
untuk beberapa kinerja tambahan, Anda harus referensi key1 = dictionary.key1daripada indekskey1 = dictionary["key1"]
Tcll
4

Anda bisa membuat Kamus kelas sehingga Anda dapat berinteraksi dengan daftar Kamus dengan mudah:

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
sumber
3

bagaimana dengan satu liner untuk membuat pasangan nilai kunci?

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

dan beberapa fungsi iterator ingin reducesecara dinamis mengubah array ke kamus

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
sumber
3

Dalam javascript modern (ES6 / ES2015), seseorang harus menggunakan struktur data Peta untuk kamus. Struktur data Peta di ES6 memungkinkan Anda menggunakan nilai arbitrer sebagai kunci.

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

Di Anda masih menggunakan ES5, cara yang benar untuk membuat kamus adalah membuat objek tanpa prototipe dengan cara berikut.

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

Ada banyak keuntungan membuat kamus tanpa objek prototipe. Blog di bawah ini layak dibaca tentang topik ini.

pola-dikt

objek-sebagai-peta

Jyoti Prasad Pal
sumber
2

Ini akan membantu satu ton untuk mengetahui apa hasil akhir yang Anda inginkan, tetapi saya pikir inilah yang Anda inginkan:

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

vars.push({key: "newkey", value: "newvalue"})
gddc
sumber
2

Saya mengalami masalah ini .. tetapi dalam for loop. Solusi teratas tidak berfungsi (ketika menggunakan variabel (dan bukan string) untuk parameter fungsi push), dan yang lainnya tidak memperhitungkan nilai kunci berdasarkan variabel. Saya terkejut pendekatan ini (yang umum di php) bekerja ..

  // 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
sumber
1

Perbaikan var dict = {}adalah menggunakan var dict = Object.create(null).

Ini akan membuat objek kosong yang tidak memiliki Object.prototypeprototipe seperti itu.

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
sumber
1

Inisialisasi Pertama Array Secara Global

var dict = []

Tambahkan Obyek ke dalam Kamus

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}]

Perbarui Objek dari Kamus

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}]

Hapus Objek dari Kamus

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

Output : 
    [0: {key: "One", value: false},
     1: {key: "Two", value: true}]
Pratik Panchal
sumber