Dynamically creating keys in a JavaScript associative array
Asked Answered
F

10

207

All the documentation I've found so far is to update keys that are already created:

 arr['key'] = val;

I have a string like this: " name = oscar "

And I want to end up with something like this:

{ name: 'whatever' }

That is, split the string and get the first element, and then put that in a dictionary.

Code

var text = ' name = oscar '
var dict = new Array();
var keyValuePair = text.split(' = ');
dict[ keyValuePair[0] ] = 'whatever';
alert( dict ); // Prints nothing.
Fenton answered 9/12, 2008 at 1:13 Comment(1)
Jump link to Eugene's answer for convenienceSalsbury
P
149

Use the first example. If the key doesn't exist it will be added.

var a = new Array();
a['name'] = 'oscar';
alert(a['name']);

Will pop up a message box containing 'oscar'.

Try:

var text = 'name = oscar'
var dict = new Array()
var keyValuePair = text.replace(/ /g,'').split('=');
dict[ keyValuePair[0] ] = keyValuePair[1];
alert( dict[keyValuePair[0]] );
Petey answered 9/12, 2008 at 1:19 Comment(4)
I ran that as a sample in Firefox just to be sure. Did you make sure to put 'name' in quotes?Petey
Uhmm nope, because, I'm creating the key "dynamically" not statically. Let me doublecheck anyway :)Fenton
Please refer to Danny's more complete explanation. You won't be able to refer to the array values in a for loop with an index (such as myarray[i]). Hope that's not too confusing.Bellanca
Even better is to use an Object (bracket {} notation) to avoid the overhead of having .length, .slice(), etc which are included in the Array prototypeToilette
T
492

Somehow all examples, while work well, are overcomplicated:

  • They use new Array(), which is an overkill (and an overhead) for a simple associative array (AKA dictionary).
  • The better ones use new Object(). It works fine, but why all this extra typing?

This question is tagged "beginner", so let's make it simple.

The über-simple way to use a dictionary in JavaScript or "Why doesn't JavaScript have a special dictionary object?":

// Create an empty associative array (in JavaScript it is called ... Object)
var dict = {};   // Huh? {} is a shortcut for "new Object()"

// Add a key named fred with value 42
dict.fred = 42;  // We can do that because "fred" is a constant
                 // and conforms to id rules

// Add a key named 2bob2 with value "twins!"
dict["2bob2"] = "twins!";  // We use the subscript notation because
                           // the key is arbitrary (not id)

// Add an arbitrary dynamic key with a dynamic value
var key = ..., // Insanely complex calculations for the key
    val = ...; // Insanely complex calculations for the value
dict[key] = val;

// Read value of "fred"
val = dict.fred;

// Read value of 2bob2
val = dict["2bob2"];

// Read value of our cool secret key
val = dict[key];

Now let's change values:

// Change the value of fred
dict.fred = "astra";
// The assignment creates and/or replaces key-value pairs

// Change the value of 2bob2
dict["2bob2"] = [1, 2, 3];  // Any legal value can be used

// Change value of our secret key
dict[key] = undefined;
// Contrary to popular beliefs, assigning "undefined" does not remove the key

// Go over all keys and values in our dictionary
for (key in dict) {
  // A for-in loop goes over all properties, including inherited properties
  // Let's use only our own properties
  if (dict.hasOwnProperty(key)) {
    console.log("key = " + key + ", value = " + dict[key]);
  }
}

Deleting values is easy too:

// Let's delete fred
delete dict.fred;
// fred is removed, but the rest is still intact

// Let's delete 2bob2
delete dict["2bob2"];

// Let's delete our secret key
delete dict[key];

// Now dict is empty

// Let's replace it, recreating all original data
dict = {
  fred:    42,
  "2bob2": "twins!"
  // We can't add the original secret key because it was dynamic, but
  // we can only add static keys
  // ...
  // oh well
  temp1:   val
};
// Let's rename temp1 into our secret key:
if (key != "temp1") {
  dict[key] = dict.temp1; // Copy the value
  delete dict.temp1;      // Kill the old key
} else {
  // Do nothing; we are good ;-)
}
Twelfthtide answered 9/12, 2008 at 3:52 Comment(4)
Hello, I know I am replying to old answer, but it ranks high on Google, so I will ask anyway. I am kind of confused at what "we can't add the original secret key because it was dynamic, we can only add static keys" means in your example.Clearheaded
It means precisely what it says: we don't know its value, so we cannot represent it as a constant, which is required when specifying a key in an object literal.Twelfthtide
However, "we can't add the original secret key because it was dynamic" is not correct by itself, even though you cannot use a variable as a key directly in {}, or as a key with dot-notation. We can still add a dynamic key through "dict[key] = val", as you show early in the example. The limitation is with using the {}-notation, rather than the key itself.Unwieldy
This looks like Sheldon Cooper's answer :)Heck
P
149

Use the first example. If the key doesn't exist it will be added.

var a = new Array();
a['name'] = 'oscar';
alert(a['name']);

Will pop up a message box containing 'oscar'.

Try:

var text = 'name = oscar'
var dict = new Array()
var keyValuePair = text.replace(/ /g,'').split('=');
dict[ keyValuePair[0] ] = keyValuePair[1];
alert( dict[keyValuePair[0]] );
Petey answered 9/12, 2008 at 1:19 Comment(4)
I ran that as a sample in Firefox just to be sure. Did you make sure to put 'name' in quotes?Petey
Uhmm nope, because, I'm creating the key "dynamically" not statically. Let me doublecheck anyway :)Fenton
Please refer to Danny's more complete explanation. You won't be able to refer to the array values in a for loop with an index (such as myarray[i]). Hope that's not too confusing.Bellanca
Even better is to use an Object (bracket {} notation) to avoid the overhead of having .length, .slice(), etc which are included in the Array prototypeToilette
C
29

JavaScript does not have associative arrays. It has objects.

The following lines of code all do exactly the same thing - set the 'name' field on an object to 'orion'.

var f = new Object(); f.name = 'orion';
var f = new Object(); f['name'] = 'orion';
var f = new Array(); f.name = 'orion';
var f = new Array(); f['name'] = 'orion';
var f = new XMLHttpRequest(); f['name'] = 'orion';

It looks like you have an associative array because an Array is also an Object - however you're not actually adding things into the array at all; you're setting fields on the object.

Now that that is cleared up, here is a working solution to your example:

var text = '{ name = oscar }'
var dict = new Object();

// Remove {} and spaces
var cleaned = text.replace(/[{} ]/g, '');

// Split into key and value
var kvp = cleaned.split('=');

// Put in the object
dict[ kvp[0] ] = kvp[1];
alert( dict.name ); // Prints oscar.
Canaliculus answered 9/12, 2008 at 1:47 Comment(2)
Assuming the text string actually does have the curly braces, you could more or less treat it as JSON.. replace the = sign with a : and you've got an object to eval..Osteoporosis
Ooops, the string isn't delimited properly. Nothing regex can't fix.Osteoporosis
V
9

In response to MK_Dev, one is able to iterate, but not consecutively (for that, obviously an array is needed).

A quick Google search brings up hash tables in JavaScript.

Example code for looping over values in a hash (from the aforementioned link):

var myArray = new Array();
myArray['one'] = 1;
myArray['two'] = 2;
myArray['three'] = 3;

// Show the values stored
for (var i in myArray) {
    alert('key is: ' + i + ', value is: ' + myArray[i]);
}
Virilism answered 9/12, 2008 at 1:37 Comment(0)
D
5

The original code (I added the line numbers so can refer to them):

1  var text = ' name = oscar '
2  var dict = new Array();
3  var keyValuePair = text.split(' = ');
4  dict[ keyValuePair[0] ] = 'whatever';
5  alert( dict ); // Prints nothing.

Almost there...

  • line 1: you should do a trim on text so it is name = oscar.

  • line 3: okay as long as you always have spaces around your equal. It might be better to not trim in line 1. Use = and trim each keyValuePair

  • add a line after 3 and before 4:

      key = keyValuePair[0];`
    
  • line 4: Now becomes:

      dict[key] = keyValuePair[1];
    
  • line 5: Change to:

      alert( dict['name'] );  // It will print out 'oscar'
    

I'm trying to say that the dict[keyValuePair[0]] does not work. You need to set a string to keyValuePair[0] and use that as the associative key. That is the only way I got mine to work. After you have set it up, you can either refer to it with numeric index or key in quotes.

Dekameter answered 19/10, 2009 at 19:10 Comment(0)
S
4

All modern browsers support a Map, which is a key/value data structure. There are a couple of reasons that make using a Map better than Object:

  • An Object has a prototype, so there are default keys in the map.
  • The keys of an Object are strings, where they can be any value for a Map.
  • You can get the size of a Map easily while you have to keep track of size for an Object.

Example:

var myMap = new Map();

var keyObj = {},
    keyFunc = function () {},
    keyString = "a string";

myMap.set(keyString, "value associated with 'a string'");
myMap.set(keyObj, "value associated with keyObj");
myMap.set(keyFunc, "value associated with keyFunc");

myMap.size; // 3

myMap.get(keyString);    // "value associated with 'a string'"
myMap.get(keyObj);       // "value associated with keyObj"
myMap.get(keyFunc);      // "value associated with keyFunc"

If you want keys that are not referenced from other objects to be garbage collected, consider using a WeakMap instead of a Map.

Snook answered 7/5, 2015 at 2:42 Comment(0)
T
3

I think it is better if you just created it like this:

var arr = [];

arr = {
   key1: 'value1',
   key2:'value2'
};

For more info, take a look at this:

JavaScript Data Structures - Associative Array

Tune answered 2/6, 2015 at 19:31 Comment(0)
L
1
var myArray = new Array();
myArray['one'] = 1;
myArray['two'] = 2;
myArray['three'] = 3;

// Show the values stored
for (var i in myArray) {
    alert('key is: ' + i + ', value is: ' + myArray[i]);
}

This is ok, but it iterates through every property of the array object.

If you want to only iterate through the properties myArray.one, myArray.two... you try like this:

myArray['one'] = 1;
myArray['two'] = 2;
myArray['three'] = 3;
myArray.push("one");
myArray.push("two");
myArray.push("three");
for(var i=0;i<maArray.length;i++){
    console.log(myArray[myArray[i]])
}

Now you can access both by myArray["one"] and iterate only through these properties.

Lactam answered 22/3, 2012 at 16:14 Comment(3)
Have you count the count of mistypes in your example? :-) maArray, forgotten closed ')'...Whin
Thanks for the example. We could unite Array and Object and work only with Object trees! Wonderful insight! It is very useful to make Object.getOwnPropertyNames(obj/array)!Whin
This syntax is invalid: for(i=0;i<maArray.length;i++{Gobang
S
1
var obj = {};

for (i = 0; i < data.length; i++) {
    if(i%2==0) {
        var left = data[i].substring(data[i].indexOf('.') + 1);
        var right = data[i + 1].substring(data[i + 1].indexOf('.') + 1);

        obj[left] = right;
        count++;
    }
}

console.log("obj");
console.log(obj);

// Show the values stored
for (var i in obj) {
    console.log('key is: ' + i + ', value is: ' + obj[i]);
}


}
};
}
Soften answered 8/9, 2015 at 6:32 Comment(1)
This is unbalanced. Where is the rest (there is a surplus of three }s)?Gobang
T
0

const arrayValues = [
                    "yPnPQpdVgzvSFdxRoyiwMxcx",
                    "yPnPQpdVgzvSFdxRoyiwMxcx",
                    "a96b3Z-rqt6U3QV_1032fxcsa",
                    "iNeoJfVnF7dXqARwnDOhj233dsd"
                ];
                
                const newArr = arrayValues.map((x)=>{
                    return {
                        "_id":x
                    }
                });
     console.log(newArr)
Telstar answered 20/1, 2023 at 6:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.