435

From post:

Sending a JSON array to be received as a Dictionary<string,string>,

I'm trying to do this same thing as that post. The only issue is that I don't know what the keys and the values are upfront. So I need to be able to dynamically add the key and value pairs and I don't know how to do that.

How can I create that object and add key value pairs dynamically?

I've tried:

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

But that doesn't work.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
KenEucker
  • 4,932
  • 5
  • 22
  • 28
  • 2
    It works great. console.log(vars); show me[ Object key: "newkey" value: "newvalue" __proto__: Object ] – Alex Pliutau Aug 25 '11 at 19:42
  • 1
    Except for it is a list, not a dictionary :\ I think the data is better represented as a list of "pairs" as well, like `list = [["key1","value1"],["key2","value2"]]`. Some other languages have a "pair", or "tuple" type. tldr for actual dict adding: `dict['key'] = "value"` – Jordan Stewart Mar 19 '20 at 11:36

17 Answers17

697

Use:

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

Basically, you're creating an object literal with two properties (called key and value) and inserting it (using push()) into the array.


This does not create a "normal" JavaScript object literal (aka map, aka hash, aka dictionary). It is however creating the structure that OP asked for (and which is illustrated in the other question linked to), which is an array of object literals, each with key and value properties. Don't ask me why that structure was required, but it's the one that was asked for.

But, but, if what you want in a plain JavaScript object - and not the structure OP asked for - see tcll's answer, though the bracket notation is a bit cumbersome if you just have simple keys that are valid JavaScript names. You can just do this:

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

Or use regular dot-notation to set properties after creating an object:

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

You do want the bracket notation if you've got keys that have spaces in them, special characters, or things like that. E.g:

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

You also want bracket notation if your keys are dynamic:

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

Note that keys (property names) are always strings, and non-string values will be coerced to a string when used as a key. E.g., a Date object gets converted to its string representation:

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

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

Note however that this doesn't necessarily "just work", as many objects will have a string representation like "[object Object]" which doesn't make for a non-unique key. So be wary of something like:

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

Despite objA and objB being completely different and unique elements, they both have the same basic string representation: "[object Object]".

The reason Date doesn't behave like this is that the Date prototype has a custom toString method which overrides the default string representation. And you can do the same:

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

(Note that since the above uses a random number, name collisions can still occur very easily. It's just to illustrate an implementation of toString.)

So when trying to use objects as keys, JavaScript will use the object's own toString implementation, if any, or use the default string representation.

E_net4
  • 27,810
  • 13
  • 101
  • 139
Flambino
  • 18,507
  • 2
  • 39
  • 58
497

Use:

var dict = {};

dict['key'] = "testing";

console.log(dict);

It works just like Python :)

Console output:

Object {key: "testing"}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Tcll
  • 7,140
  • 1
  • 20
  • 23
59

It’s as simple as:

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

or

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

Then

blah.key3 = value3; // Add a new key/value pair
blah.key2; // Returns value2
blah['key2']; // Also returns value2
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Simon Sarris
  • 62,212
  • 13
  • 141
  • 171
  • 1
    @KenEucker I think it's useful to have wrong answers in questions like this. Especially if someone explains why they're wrong, it's a good learning resource. – CJBrew Sep 28 '16 at 11:12
34

Since you've stated that you want a dictionary object (and not an array like I assume some understood) I think this is what you are after:

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
  • 12,363
  • 5
  • 36
  • 59
  • The other solution using .push into an array works for my uses, but I assume this would also work if I tried it. – KenEucker Aug 25 '11 at 20:12
  • 3
    Unless I misunderstand what a Dictionary object is, your question is misleading then. How would you retrieve a value by key from your array? – ZenMaster Aug 25 '11 at 20:15
  • I am using JSON.stringify on this object and then catching it with a controller in MVC 3. This is just so that it is formatted properly before stringifying it and sending it along. – KenEucker Aug 25 '11 at 21:09
31

JavaScript's Object is in itself like a dictionary. No need to reinvent the wheel.

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
}

Fiddle

Jani Hyytiäinen
  • 5,293
  • 36
  • 45
15

You can use maps with Map, like this:

var sayings = new Map();
sayings.set('dog', 'woof');
sayings.set('cat', 'meow');
Pang
  • 9,564
  • 146
  • 81
  • 122
13

With ES6, you can do this:

let cake = '';

let pan = {
  [cake]: '',
};

// Output -> { '': '' }

Old Way (vanilla JavaScript)

let cake = '';
let pan = {};
pan[cake] = '';

// Output -> { '': '' }
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Junaid
  • 4,682
  • 1
  • 34
  • 40
  • I like this solution, as it is updated for the modern time and is pretty elegant. Thank you for your contribution. This would have been a valid solution for what I needed at the time. – KenEucker Dec 07 '20 at 03:58
9

I happened to walk across this question looking for something similar. It gave me enough info to run a test to get the answer I wanted. So if anyone else wants to know how to dynamically add to or lookup a {key: 'value'} pair in a JavaScript object, this test should tell you all you might need to know.

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

output

initialValue
{ initialkey: 'initialValue',
  something: 'value1',
  somethingElse: 'value2' }
user2301449
  • 91
  • 1
  • 2
  • 2
    This is not a question. What you should do instead is ask the question and then answer it yourself. That would be much easier to understand and organize. – SalmonKiller Jan 02 '15 at 02:02
  • 2
    thanks @SalmonKiller i was unsure of proper terminology to write my own question and expect it to be understood but then i happened across this in my search all the information was there but spread out between several answers so i answered the concept of this question in a way that would answer it for someone else who stumbled on to this question looking for the same thing as me – user2301449 Jan 02 '15 at 02:41
  • 1
    LOL. I was reviewing this and it looked like a question instead of an answer. Sorry, man! – SalmonKiller Jan 02 '15 at 02:43
  • Thank you for adding this. You could also put it into a fiddle like the answer above. – KenEucker May 14 '16 at 17:50
7
var dictionary = {};//create new object
dictionary["key1"] = value1;//set key1
var key1 = dictionary["key1"];//get key1
SharpCoder
  • 18,279
  • 43
  • 153
  • 249
  • for some added performance, you should reference `key1 = dictionary.key1` rather than index `key1 = dictionary["key1"]` – Tcll Mar 21 '16 at 18:21
7

In modern JavaScript (ES6/ES2015), one should use the Map data structure for a dictionary. The Map data structure in ES6 lets you use arbitrary values as keys.

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

In you are still using ES5, the correct way to create dictionary is to create object without a prototype in the following way.

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

There are many advantages of creating a dictionary without a prototype object. The below blog posts are worth reading on this topic.

dict-pattern

objects-as-maps

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Jyoti Prasad Pal
  • 1,569
  • 3
  • 26
  • 41
6

First initialise the array globally:

var dict = []

Add the object into the dictionary

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

Update the object from the dictionary

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

Delete an object from the dictionary

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

Output:

    [0: {key: "One", value: false},
     1: {key: "Two", value: true}]
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Pratik Panchal
  • 339
  • 5
  • 13
5

You could create a class Dictionary so you can interact with the Dictionary list easily:

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
  • 439
  • 7
  • 20
4

An improvement on var dict = {} is to use var dict = Object.create(null).

This will create an empty object that does not have Object.prototype as its 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 :)")
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
WoodenKitty
  • 6,521
  • 8
  • 53
  • 73
  • Good point, as you would otherwise get a dictionary full of: `__defineGetter__: function __defineGetter__() __defineSetter__: function __defineSetter__() __lookupGetter__: function __lookupGetter__() __lookupSetter__: function __lookupSetter__() __proto__: ​constructor: function Object() hasOwnProperty: function hasOwnProperty() hasProperty: function value(prop) isPrototypeOf: function isPrototypeOf() propertyIsEnumerable: function propertyIsEnumerable() toLocaleString: function toLocaleString() toString: function toString() ​valueOf: function valueOf()` – Miros Jun 09 '21 at 21:28
  • Lifesaver! As a newbie I was a bit confused when `dict["constructor"].item` kept crashing my app. – l33t Aug 15 '21 at 21:41
4

Use a one-liner for creating a key value pair:

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

And some iterator function like reduce to dynamically convert an array to a dictionary

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);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Dan Dohotaru
  • 2,809
  • 19
  • 15
3

I ran into this problem... but within a for loop. The top solution did not work (when using variables (and not strings) for the parameters of the push function), and the others did not account for key values based on variables. I was surprised this approach (which is common in PHP) worked...

  // 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];
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
redcap3000
  • 928
  • 1
  • 8
  • 15
2

In case if someone needs to create a dictionary object dynamically you can use the following code snippet

let vars = [{key:"key", value:"value"}, {key:"key2", value:"value2"}];
let dict = {}
vars.map(varItem => {
             dict[varItem.key] = varItem.value
         })

console.log(dict)
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Abdulhakim Zeinu
  • 3,333
  • 1
  • 30
  • 37
0

You can initialize the dictionary like

var vars = {
    "key1": "Search",
    "key2": "View"
};

And access it like

console.log(vars["key1"]);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Fatehi_Alqadasi
  • 548
  • 5
  • 14