13

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
  • 7,533
  • 18
  • 68
  • 97
  • 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

26
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
  • 741,623
  • 53
  • 500
  • 612
5

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
  • 365
  • 1
  • 4
  • 6
  • 1
    What a neat solution. Thanks for the help – enigma6174 May 20 '21 at 13:47
  • It is unreadable. Please do not use arrow operators in maintainable code. Thank you. – TomeeNS Aug 17 '22 at 04:37
  • Not all javascript/typescript programmers adopt as their primary language, some imperative one. Someone can look at an imperative code and consider it bloated and having unnecessary mutations. Where did you get this about not using the arrow operator in maintainable code? I can see lots of them in lodash, react and axios source code. In fp-ts, I can only see arrow functions. – l30.4l3x Aug 17 '22 at 13:07
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
  • 42,889
  • 6
  • 74
  • 90
  • 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,170
  • 7
  • 25
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,304
  • 1
  • 15
  • 29
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,638
  • 2
  • 18
  • 27