March 27, 2012
Join 2 arrays in object with repeated keys
Question by DannYO
I have 2 arrays of the same length like this:
a = [12,21,21,13,13,13,13,31];
b = [4,7,4,6,2,9,4,1];
The first array are the keys and the second array the values, but if the key is repeated the the values should be grouped in the corresponding key instead of being replaced.
The object should look like so:
o = {
12: [4],
21: [7,4],
13: [6,2,9,4],
31: [1]
}
And here what I tried:
var o = {};
for ( var index in a) {
o[a[index]] = [];
o[a[index]].push(b[index]);
}
Answer by T.J. Crowder
Don’t use for..in
to loop through arrays (unless they’re sparse arrays and you know what you’re doing; details).
Other than that, you’re on the right track, but you have to check to see whether the array already exists before overwriting it. So:
var o = {}, key, entry;
for (index = 0; index < a.length; ++index) {
// Get the key
key = a[index];
// Get the entry's array if it already exists
entry = o[key];
if (!entry) {
// It doesn't exist, create it and remember it in the object
o[key] = entry = [];
}
// Put this value in it
entry.push(b[index]);
}
Or a couple of small optimizations:
var o = {}, key, entry, len;
for (index = 0, len = a.length; index < len; ++index) {
// Get the key
key = a[index];
// Get the entry's array if it already exists
entry = o[key];
if (!entry) {
// It doesn't exist, create it and remember it in the object,
// including this value as we go
o[key] = [b[index]];
}
else {
// Already existed, add this value to it
entry.push(b[index]);
}
}
If you’re using an ES5-enabled environment (or you include an ES5 shim), you can use forEach
:
var o = {};
a.forEach(function(key, index) {
var entry;
// Get the entry's array if it already exists
entry = o[key];
if (!entry) {
// It doesn't exist, create it and remember it in the object,
// including this value as we go
o[key] = [b[index]];
}
else {
// Already existed, add this value to it
entry.push(b[index]);
}
});
Answer by Starx
Here is a function you can use from phpjs.com
for this
function array_combine (keys, values) {
// Creates an array by using the elements of the first parameter as keys and the elements of the second as the corresponding values
var new_array = {}, keycount = keys && keys.length,
i = 0;
// input sanitation
if (typeof keys !== 'object' || typeof values !== 'object' || // Only accept arrays or array-like objects typeof keycount !== 'number' || typeof values.length !== 'number' || !keycount) { // Require arrays to have a count
return false;
}
// number of elements does not match if (keycount != values.length) {
return false;
}
for (i = 0; i < keycount; i++) { new_array[keys[i]] = values[i];
}
return new_array;
}