Як створити словник і динамічно додавати пари ключ-значення?


323

З поста:

Надсилання масиву JSON для отримання у словнику <рядок, рядок>

Я намагаюся зробити це те саме, що і на цій посаді. Єдине питання полягає в тому, що я не знаю, які ключі та значення знаходяться наперед. Тому мені потрібно вміти динамічно додавати пари ключів і значень, і я не знаю, як це зробити.

Хтось знає, як створити цей об’єкт і додавати пари ключових значень динамічно?

Я спробував:

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

Але це не працює.


2
Це чудово працює. console.log (vars); покажіть мені [Object key: "newkey" value: "newvalue" proto : Object]
Alex Pliutau

За винятком цього списку, а не словника: \ Я думаю, що дані краще представлені як список "пар", як list = [["key1","value1"],["key2","value2"]]. Деякі інші мови мають тип "пара" або "кортеж". tldr для додавання фактичного дикту:dict['key'] = "value"
Джордан Стюарт

Відповіді:


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

В основному ви створюєте об'єкт буквально з двома властивостями (називається keyта value) та вставляєте його (використовуючи push()) у масив.


Редагувати: Таким чином, майже через 5 років ця відповідь отримує зворотній зв'язок, оскільки це не створює "нормального" об'єкта JS-літералу (ака-карта, ака-хеш, ака-словник).
Це буде , однак створення структури , що ОП просили (і який проілюстрований на інше питання пов'язаний з), який є масивом литералов об'єктів , кожен з яких має keyі valueвластивості. Не запитуйте мене, навіщо потрібна така структура, але саме про це вимагали.

Але, але, якщо ви хочете в простому JS-об'єкті, а не в структурі, про яку попросили, - дивіться відповідь 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це не асоціативний словник. Це масив об'єктів, кожен з яких трохи схожий на словник з двома клавішами: "ключ" і "значення".
Роман Старков

1
У вас є масив, який називається просто "dict".
Ян Кю Пеблик

2
Вдячні за оновлення та надайте додаткову інформацію.
Яків

410
var dict = {};

dict['key'] = "testing";

console.log(dict);

працює так само, як python :)

вихід консолі:

Object {key: "testing"} 

3
Це, безумовно, найкращий підхід до складання словника, і це правильна відповідь!
Роман

3
Дуже важливо ініціалізуватися дужками, {}а не дужками
Jaider

Я також використовую основні об'єкти як такі словники. Радий бачити, що це правильний шлях!
TKoL

5
"Краса" javascript! Об'єкт є
фактично

1
@Azurespot ключ може бути будь-яким хешируемым, зрештою, ключі впорядковуються хешем, який у 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
@KenEucker Я думаю, що корисно мати неправильні відповіді на подібні питання. Особливо, якщо хтось пояснює, чому вони помиляються, це хороший навчальний ресурс.
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

Інше рішення, що використовує .push в масив, працює для мого використання, але я припускаю, що це також спрацювало, якби я спробував це.
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 Я не знав належної термінології, щоб написати власне запитання, і очікував, що воно буде зрозуміле, але тоді я трапився через це в моєму пошуку, вся інформація була там, але розкладалася між кількома відповідями, тому я відповів на концепцію цього питання в спосіб, який би відповів на нього, щоб хтось інший, хто наткнувся на це питання, шукав те саме, що і я
user2301449

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

У сучасному javascript (ES6 / ES2015) слід використовувати структуру даних Map для словника. Структура даних Map у 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;

Є багато переваг створення словника без об’єкта-прототипу. Нижче щоденники варто прочитати на цю тему.

малюнок-малюнок

об'єкти-карти


2

Це допоможе тоні дізнатися, який ваш кінцевий бажаний результат, але я думаю, що саме цього ви хочете:

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

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

2

Я зіткнувся з цією проблемою .. але всередині циклу for. Верхнє рішення не працювало (при використанні змінних (а не рядків) для параметрів функції push), а інші не враховували ключових значень на основі змінних. Я був здивований, що цей підхід (який є загальним для 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}]
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.