จะสร้างพจนานุกรมและเพิ่มคู่คีย์ - ค่าแบบไดนามิกได้อย่างไร


323

จากโพสต์:

การส่งอาร์เรย์ JSON เพื่อรับเป็น Dictionary <string, string>

ฉันพยายามทำสิ่งเดียวกันกับโพสต์นั้น ปัญหาเดียวคือฉันไม่รู้ว่ากุญแจและค่าคืออะไร ดังนั้นฉันต้องสามารถเพิ่มคีย์และคู่ค่าแบบไดนามิกและฉันไม่รู้วิธีการทำ

ไม่มีใครรู้วิธีสร้างวัตถุนั้นและเพิ่มคู่ของค่าคีย์แบบไดนามิกหรือไม่

ฉันพยายามแล้ว:

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

แต่นั่นไม่ได้ผล


2
มันใช้งานได้ดี console.log (vars); แสดงให้ฉัน [คีย์วัตถุ: "newkey" ค่า: "newvalue" proto : Object]
Alex Pliutau

ยกเว้นมันเป็นรายการที่ไม่พจนานุกรม: \ ผมคิดว่าข้อมูลที่เป็นตัวแทนที่ดีขึ้นเป็นรายการของ "คู่" list = [["key1","value1"],["key2","value2"]]ได้เป็นอย่างดีเช่น ภาษาอื่นบางภาษามีประเภท "pair" หรือ "tuple" tldr สำหรับการเพิ่ม dict จริง:dict['key'] = "value"
Jordan Stewart

คำตอบ:


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

โดยทั่วไปคุณจะสร้างวัตถุตามตัวอักษรที่มี 2 คุณสมบัติ (เรียกว่าkeyและvalue) และแทรก (ใช้push()) ลงในอาร์เรย์


แก้ไข:ดังนั้นเกือบ 5 ปีต่อมาคำตอบนี้กำลังลดลงเพราะไม่ได้สร้างตัวอักษรวัตถุ "ปกติ" JS (แผนที่อาคา, อาคาแฮ, พจนานุกรมอาคา) อย่างไรก็ตาม
มันกำลังสร้างโครงสร้างที่ OP ขอ (ซึ่งแสดงให้เห็นในคำถามอื่นที่เชื่อมโยงกับ) ซึ่งเป็นอาร์เรย์ของตัวอักษรของวัตถุแต่ละตัวมีkeyและvalueคุณสมบัติ อย่าถามฉันว่าทำไมโครงสร้างนั้นถึงต้องการ แต่มันเป็นโครงสร้างที่ถูกถาม

แต่ถ้าสิ่งที่คุณต้องการในวัตถุ JS ธรรมดา - และไม่ใช่โครงสร้าง OP ขอ - ดูคำตอบของ tcllแม้ว่าสัญกรณ์วงเล็บจะค่อนข้างยุ่งยากถ้าคุณมีคีย์ง่ายๆที่เป็นชื่อ JS ที่ถูกต้อง คุณสามารถทำสิ่งนี้:

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

หรือใช้เครื่องหมายจุดปกติเพื่อตั้งค่าคุณสมบัติหลังจากสร้างวัตถุ:

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

คุณทำต้องการโน้ตวงเล็บถ้าคุณได้มีคีย์ที่มีช่องว่างในพวกเขาอักขระพิเศษหรือสิ่งที่ต้องการที่ เช่น:

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

นอกจากนี้คุณยังต้องการเครื่องหมายวงเล็บหากคีย์ของคุณเป็นแบบไดนามิก:

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

โปรดทราบว่าคีย์ (ชื่อคุณสมบัติ) เป็นสตริงเสมอและค่าที่ไม่ใช่สตริงจะถูกบังคับให้เป็นสตริงเมื่อใช้เป็นคีย์ เช่นDateวัตถุได้รับการแปลงเป็นตัวแทนสตริง:

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

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

อย่างไรก็ตามโปรดทราบว่าสิ่งนี้ไม่จำเป็นต้อง "แค่ใช้งานได้" เนื่องจากวัตถุจำนวนมากจะมีการแสดงสตริงเหมือน"[object Object]"ที่ไม่ได้ทำขึ้นสำหรับคีย์ที่ไม่ซ้ำกัน ดังนั้นจงระวังสิ่งที่ชอบ:

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

แม้จะมีobjAและเป็นองค์ประกอบที่สมบูรณ์แตกต่างและไม่ซ้ำกันพวกเขาทั้งสองมีเหมือนกันแสดงสตริงพื้นฐานobjB"[object Object]"

เหตุผลที่Dateไม่ทำงานเช่นนี้คือDateต้นแบบมีtoStringวิธีการที่กำหนดเองซึ่งแทนที่การแสดงสตริงเริ่มต้น และคุณสามารถทำเช่นเดียวกัน:

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

(โปรดทราบว่าเนื่องจากด้านบนใช้หมายเลขสุ่มการชนชื่อสามารถเกิดขึ้นได้ง่ายมากมันเป็นเพียงการแสดงให้เห็นถึงการนำไปปฏิบัติtoString)

ดังนั้นเมื่อพยายามใช้วัตถุเป็นคีย์ JS จะใช้การtoStringดำเนินการของวัตถุเองถ้ามีหรือใช้การแทนค่าสตริงเริ่มต้น


2
เชื่อมโยงกันไหม
Csaba Toth

1
@CsabaToth ไม่dictไม่ใช่พจนานุกรมเชื่อมโยง มันเป็นอาร์เรย์ของวัตถุแต่ละอันมีลักษณะคล้ายพจนานุกรมที่มีสองปุ่ม: "key" และ "value"
Roman Starkov

1
สิ่งที่คุณมีคืออาร์เรย์ที่มีชื่อว่า 'dict'
ม.ค. Kyu Peblik

2
ขอบคุณการปรับปรุงและติดตามข้อมูลพิเศษ
จาค็อบ

410
var dict = {};

dict['key'] = "testing";

console.log(dict);

ทำงานเหมือนงูหลาม :)

เอาท์พุทคอนโซล:

Object {key: "testing"} 

3
นี่เป็นวิธีที่ดีที่สุดในการสร้างพจนานุกรมและเป็นคำตอบที่ถูกต้อง!
Roman

3
สำคัญมากในการเริ่มต้นด้วยวงเล็บ{}ไม่ใช่วงเล็บ
Jaider

ฉันยังใช้วัตถุพื้นฐานเป็นพจนานุกรมเช่นนี้ ดีใจที่เห็นว่าเป็นวิธีที่ถูกต้อง!
TKoL

5
'ความงาม' ของ javascript! Object IS เป็นจริงคู่พจนานุกรมคีย์ค่าตัวเอง
100r

1
@Azurespot กุญแจสามารถ hashable อะไรก็ได้กุญแจถูกเรียงลำดับโดย hash หลังจากทั้งหมดซึ่งใน python3 ต่างกันในการวิ่งแต่ละครั้ง
Tcll

54

มันง่ายเหมือน:

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

หรือ

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

แล้วก็

blah.key3 = value3; // add a new key/value pair
blah.key2; // returns value2
blah['key2']; // also returns value2

1
@ เคนเกอร์ฉันคิดว่ามันมีประโยชน์ที่จะมีคำตอบที่ผิดในคำถามเช่นนี้ โดยเฉพาะถ้ามีคนอธิบายว่าทำไมพวกเขาถึงผิดมันเป็นแหล่งเรียนรู้ที่ดี
CJBrew

32

เนื่องจากคุณระบุว่าคุณต้องการวัตถุพจนานุกรม (และไม่ใช่อาร์เรย์เหมือนที่ฉันเข้าใจบางอย่าง) ฉันคิดว่านี่คือสิ่งที่คุณเป็นหลังจาก:

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

โซลูชันอื่นที่ใช้. พุชเป็นอาเรย์ใช้งานได้กับการใช้งานของฉัน
KenEucker

2
ถ้าฉันไม่เข้าใจว่าวัตถุในพจนานุกรมคืออะไรคำถามของคุณจะทำให้เข้าใจผิด คุณจะดึงค่าด้วยรหัสจากอาร์เรย์ของคุณได้อย่างไร?
ZenMaster

ฉันใช้ JSON.stringify บนวัตถุนี้แล้วจับมันด้วยคอนโทรลเลอร์ใน MVC 3 นี่เป็นเพียงการจัดรูปแบบให้ถูกต้องก่อนที่จะทำให้เป็นสตริงและส่งไปตามนั้น
KenEucker

23

JavaScript Object อยู่ในตัวมันเองเหมือนพจนานุกรม ไม่จำเป็นต้องบูรณาการล้อ

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
}

ซอ



9

ฉันบังเอิญเดินข้ามคำถามนี้เพื่อค้นหาสิ่งที่คล้ายกัน มันให้ข้อมูลฉันเพียงพอที่จะทำการทดสอบเพื่อรับคำตอบที่ฉันต้องการ ดังนั้นหากใครต้องการทราบวิธีเพิ่มหรือค้นหาคู่ {key: 'value'} แบบไดนามิกในวัตถุ JavaScript การทดสอบนี้ควรบอกคุณทั้งหมดที่คุณอาจจำเป็นต้องรู้

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

เอาท์พุต

initialValue
{ initialkey: 'initialValue',
  something: 'value1',
  somethingElse: 'value2' }

2
นี่ไม่ใช่คำถาม สิ่งที่คุณควรทำคือถามคำถามแล้วตอบด้วยตนเอง นั่นจะง่ายกว่าที่จะเข้าใจและจัดระเบียบ
SalmonKiller

1
ขอบคุณ @SalmonKiller ฉันไม่แน่ใจในคำศัพท์ที่เหมาะสมในการเขียนคำถามของฉันและคาดว่าจะเข้าใจ แต่แล้วฉันก็เกิดขึ้นในการค้นหาของฉันข้อมูลทั้งหมดอยู่ที่นั่น แต่กระจายออกไประหว่างคำตอบต่าง ๆ ดังนั้นฉันตอบแนวคิดของคำถามนี้ใน วิธีที่จะตอบมันสำหรับคนอื่นที่สะดุดกับคำถามนี้มองหาสิ่งเดียวกันกับฉัน
2301449

1
ฮ่า ๆ. ฉันตรวจทานสิ่งนี้และดูเหมือนคำถามแทนที่จะเป็นคำตอบ ขอโทษ!
SalmonKiller

ขอบคุณที่เพิ่มสิ่งนี้ คุณสามารถใส่ซอให้เหมือนคำตอบด้านบนได้
KenEucker

8
var dictionary = {};//create new object
dictionary["key1"] = value1;//set key1
var key1 = dictionary["key1"];//get key1

สำหรับการเพิ่มประสิทธิภาพบางอย่างคุณควรอ้างอิงkey1 = dictionary.key1มากกว่าดัชนีkey1 = dictionary["key1"]
Tcll

4

คุณสามารถสร้างคลาสพจนานุกรมเพื่อให้คุณสามารถโต้ตอบกับรายการพจนานุกรมได้อย่างง่ายดาย:

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


3

ซับในสำหรับการสร้างคู่ค่าคีย์เป็นอย่างไร

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

และฟังก์ชั่นตัววนซ้ำบางตัวต้องการreduceแปลงอาเรย์เป็นพจนานุกรมแบบไดนามิก

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


3

ในจาวาสคริปต์สมัยใหม่ (ES6 / ES2015) เราควรใช้โครงสร้างข้อมูลแผนที่สำหรับพจนานุกรม โครงสร้างข้อมูลแผนที่ใน ES6 ช่วยให้คุณใช้ค่าโดยพลการเป็นคีย์

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

ในคุณยังคงใช้ ES5 วิธีที่ถูกต้องในการสร้างพจนานุกรมคือการสร้างวัตถุโดยไม่มีต้นแบบในวิธีต่อไปนี้

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

มีข้อดีหลายประการในการสร้างพจนานุกรมโดยไม่มีวัตถุต้นแบบ บล็อกด้านล่างมีมูลค่าการอ่านในหัวข้อนี้

Dict รูปแบบ

วัตถุ as-แผนที่


2

มันจะช่วยให้คุณรู้ว่าผลลัพธ์ที่คุณต้องการคืออะไร แต่ฉันคิดว่านี่คือสิ่งที่คุณต้องการ:

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

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

2

ฉันพบปัญหานี้ แต่ภายในวง โซลูชันระดับสูงไม่ทำงาน (เมื่อใช้ตัวแปร (และไม่ใช้สตริง) สำหรับพารามิเตอร์ของฟังก์ชันพุช) และอื่น ๆ ไม่ได้คำนึงถึงค่าคีย์ตามตัวแปร ฉันประหลาดใจที่วิธีนี้ (ซึ่งเป็นเรื่องปกติใน PHP) ทำงาน ..

  // 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];

1

การปรับปรุงในคือการใช้งานvar dict = {}var dict = Object.create(null)

นี้จะสร้างวัตถุว่างเปล่าที่ไม่ได้มีความObject.prototypeเป็นมันต้นแบบ

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

1

อาร์เรย์เริ่มต้นแรกทั่วโลก

var dict = []

เพิ่มวัตถุลงในพจนานุกรม

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

อัปเดตวัตถุจากพจนานุกรม

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

ลบวัตถุออกจากพจนานุกรม

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

Output : 
    [0: {key: "One", value: false},
     1: {key: "Two", value: true}]
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.