Is there a simple way in javascript to take a flat array and convert into an object with the even-indexed members of the array as properties and odd-indexed members as corresponding values (analgous to ruby's Hash[*array]
)?
For example, if I have this:
[ 'a', 'b', 'c', 'd', 'e', 'f' ]
Then I want this:
{ 'a': 'b', 'c': 'd', 'e': 'f' }
The best I've e up with so far seems more verbose than it has to be:
var arr = [ 'a', 'b', 'c', 'd', 'e', 'f' ];
var obj = {};
for (var i = 0, len = arr.length; i < len; i += 2) {
obj[arr[i]] = arr[i + 1];
}
// obj => { 'a': 'b', 'c': 'd', 'e': 'f' }
Is there a better, less verbose, or more elegant way to do this? (Or I have just been programming in ruby too much lately?)
I'm looking for an answer in vanilla javascript, but would also be interested if there is a better way to do this if using undercore.js
or jQuery
. Performance is not really a concern.
Is there a simple way in javascript to take a flat array and convert into an object with the even-indexed members of the array as properties and odd-indexed members as corresponding values (analgous to ruby's Hash[*array]
)?
For example, if I have this:
[ 'a', 'b', 'c', 'd', 'e', 'f' ]
Then I want this:
{ 'a': 'b', 'c': 'd', 'e': 'f' }
The best I've e up with so far seems more verbose than it has to be:
var arr = [ 'a', 'b', 'c', 'd', 'e', 'f' ];
var obj = {};
for (var i = 0, len = arr.length; i < len; i += 2) {
obj[arr[i]] = arr[i + 1];
}
// obj => { 'a': 'b', 'c': 'd', 'e': 'f' }
Is there a better, less verbose, or more elegant way to do this? (Or I have just been programming in ruby too much lately?)
I'm looking for an answer in vanilla javascript, but would also be interested if there is a better way to do this if using undercore.js
or jQuery
. Performance is not really a concern.
-
4
You can create your own function, then it's quite short:
var obj = transform(arr);
;) – Felix Kling Commented Jan 5, 2012 at 22:54 - That seems rather concise to me. – ChaosPandion Commented Jan 5, 2012 at 22:54
- You have it right. The loop you provided is the correct way to do it. – Joseph Marikle Commented Jan 5, 2012 at 22:55
- Yeah what you have is optimal. – mattacular Commented Jan 5, 2012 at 23:02
- other than your loop breaking if your arr has an odd number of elements, what you did looks fine; just wrap it in a function as already suggested. – Darko Commented Jan 5, 2012 at 23:03
4 Answers
Reset to default 9Pretty sure this will work and is shorter:
var arr = [ 'a', 'b', 'c', 'd', 'e', 'f' ];
var obj = {};
while (arr.length) {
obj[arr.shift()] = arr.shift();
}
See shift().
var arr = [ 'a', 'b', 'c', 'd', 'e', 'f' ];
var obj = arr.reduce( function( ret, value, i, values ) {
if( i % 2 === 0 ) ret[ value ] = values[ i + 1 ];
return ret;
}, { } );
If you need it multiple times you can also add a method to the Array.prototype:
Array.prototype.to_object = function () {
var obj = {};
for(var i = 0; i < this.length; i += 2) {
obj[this[i]] = this[i + 1];
}
return obj
};
var a = [ 'a', 'b', 'c', 'd', 'e', 'f' ];
a.to_object(); // => { 'a': 'b', 'c': 'd', 'e': 'f' }
You could first chunk your array into groups of two:
[['a', 'b'], ['c', 'd'], ['e', 'f']]
so that your data is now in a valid format to be used by Object.fromEntries()
, which will build your object for you:
const chunk = (arr, size) => arr.length ? [arr.slice(0, size), ...chunk(arr.slice(size), size)] : [];
const arr = ['a', 'b', 'c', 'd', 'e', 'f'];
const res = Object.fromEntries(chunk(arr, 2));
console.log(res); // {a: "b", c: "d", e: "f"}
With underscore.js and lodash, you don't need to implement the chunk()
method yourself, and can instead use _.chunk()
, a method built into both libraries. The full lodash equivalent of the above would be:
// lodash
> _.fromPairs(_.chunk(arr, 2));
> {a: "b", c: "d", e: "f"}
Using _.fromPairs
provides better browser support, so if using lodash, it is preferred over Object.fromEntries()
Similarly, we can use _.object()
if you're using underscore.js to build the object:
// underscore.js
> _.object(_.chunk(arr, 2));
> {a: "b", c: "d", e: "f"}