14

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
}
4
  • 2
    What's hops? Don't you mean var datum = input[i];? P.S. Don't use for..in for arrays: stackoverflow.com/a/500531 Commented Oct 25, 2013 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. Commented Oct 25, 2013 at 21:05
  • Ah, thanks. My fault, typo. Commented Oct 25, 2013 at 21:06
  • 2
    A JavaScript "dictionary" is called an object. Just FYI. Commented Oct 25, 2013 at 21:07

8 Answers 8

28
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.

Sign up to request clarification or add additional context in comments.

1 Comment

You were a tad bit faster than me. Same exact answer :)
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] }), {})

2 Comments

It is unreadable. Please do not use arrow operators in maintainable code. Thank you.
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.
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;

}, {});

2 Comments

Probably not the clearest for newbie but I like it :)
@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.
1
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);

Comments

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

Comments

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

Comments

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

Comments

0

PRO-TIP:

You can define it as a expression so you can reuse it multiple times and keep your code readable.

Examples:

const pushToDict = (dictionary:any, key:any, value:any) => {
    (dictionary[key] = dictionary[key] || []).push(value);
};

typescript version

const pushToDict = (dictionary, key, value) => {
    (dictionary[key] = dictionary[key] || []).push(value);
};

javascript version

And you call it like this...

Example of usage:

pushToDict(dict, key, value);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.