10

I am trying to create the following data structure in javascript:

d = {"foo": [3, 77, 100], "bar": [10], "baz": [99], "biff": [10]}

My starting data structure is a a list of dictionaries:

input = [{"key": "foo", "val": 3}, {"key": "bar", "val": 10}, {"key": "foo", "val": 100}, {"key": "baz", "val": 99}, {"key": "biff", "val": 10}, {"key": "foo", "val": 77]

How can I generate my desired data structure? The following code doesn't seem to append values to the value array.

var d = {}

for (var i in input) {
    var datum = input[i];
    d[datum.key] = datum.val
}
turtle
  • 6,769
  • 16
  • 61
  • 87
  • 2
    What's `hops`? Don't you mean `var datum = input[i];`? P.S. Don't use `for..in` for arrays: http://stackoverflow.com/a/500531 – gen_Eric Oct 25 '13 at 21:03
  • 1
    Iterate the `input`, see if `d` has a property for each value of `"key"`, and if not, give `d` a property using that value, and assign an array. Then push the value of `"val"` into the Array. – Blue Skies Oct 25 '13 at 21:05
  • Ah, thanks. My fault, typo. – turtle Oct 25 '13 at 21:06
  • 2
    A JavaScript "dictionary" is called an object. Just FYI. – JJJ Oct 25 '13 at 21:07

7 Answers7

22
for (var i = 0; i < input.length; i++) {
    var datum = input[i];
    if (!d[datum.key]) {
        d[datum.key] = [];
    }
    d[datum.key].push(datum.val);
}

FYI, you shouldn't use for (var i in input) to iterate over an array.

Barmar
  • 669,327
  • 51
  • 454
  • 560
4

Another alternative:

const input = [{ "key": "foo", "val": 3 }, { "key": "bar", "val": 10 }, { "key": "foo", "val": 100 }, { "key": "baz", "val": 99 }, { "key": "biff", "val": 10 }, { "key": "foo", "val": 77 }]
const dict = {}

input.forEach(({ key, val }) =>
    key in dict ? dict[key].push(val) : dict[key] = [val] )

console.log(dict);

And a one-liner, with immutability

input.reduce((dict, { key, val }) => ({ ...dict, [key]: [...dict[key] || [], val] }), {})
l30.4l3x
  • 169
  • 1
  • 2
  • 4
1

Another way, with reduce.

var d = input.reduce(function (res, item) {
    var key = item.key;

    if (!res[key]) res[key] = [item.val];
    else res[key].push(item.val);

    return res;

}, {});
plalx
  • 41,415
  • 5
  • 69
  • 87
  • Probably not the clearest for newbie but I like it :) – techie.brandon Oct 25 '13 at 21:18
  • @user1523882, Yeah it might not be, but I really like to make use of the `initialValue` of the reduce functions to build maps like this. Once you get used to it it's nice because you can do it in a single *external* statement. – plalx Oct 25 '13 at 21:31
1

You should be do the next:

for (var i in input){
    var datuml = input[i];    
    if(!d[datuml.key]){
        d[datuml.key]=[];
    }
    d[datuml.key].push(datuml.val);
}
gartox
  • 891
  • 10
  • 6
0

you will have more then 1 key? Well, I think you want something like convert JSON to ArrayString.

Check this Convert JSON To Array Javascript and this How to convert JSON object to JavaScript array

etc

Community
  • 1
  • 1
X-Pippes
  • 1,142
  • 7
  • 24
0

Please try the following:

        var input = [{ "key": "foo", "val": 3 }, { "key": "bar", "val": 10 }, { "key": "foo", "val": 100 }, { "key": "baz", "val": 99 }, { "key": "biff", "val": 10 }, { "key": "foo", "val": 77 }];
        var d = {};

        for (var i = 0; i < input.length; i++) {
            var entry = input[i];
            if (d[entry.key] === undefined) d[entry.key] = [];
            d[entry.key].push(entry.val);
        }

        alert(JSON.stringify(d));
Wagner DosAnjos
  • 6,156
  • 1
  • 12
  • 26
0
var result = {}
input.forEach(function(keyObject){
  //Make array for key if doesn't exist
  result[keyObject.key] = result[keyObject.key] ? result[keyObject.key] : [];
  //Add value to array
  result[keyObject.key].push(keyObject.val);
});
console.log(result);
techie.brandon
  • 1,558
  • 2
  • 15
  • 27