87

I have an array:

[ [ 'cardType', 'iDEBIT' ],
  [ 'txnAmount', '17.64' ],
  [ 'txnId', '20181' ],
  [ 'txnType', 'Purchase' ],
  [ 'txnDate', '2015/08/13 21:50:04' ],
  [ 'respCode', '0' ],
  [ 'isoCode', '0' ],
  [ 'authCode', '' ],
  [ 'acquirerInvoice', '0' ],
  [ 'message', '' ],
  [ 'isComplete', 'true' ],
  [ 'isTimeout', 'false' ] ]

But I can't access data via an array's key, e.g. arr['txnId'] does not return 20181. How can I convert the above array of tuples into an object, so that I can easily access data by key.

2

14 Answers 14

105

As baao notes, since 2019 you can use Object.fromEntries(arr) (docs) to do exactly this on all modern browsers:

var arr = [['cardType', 'iDEBIT'],
  ['txnAmount', '17.64'],
  ['txnId', '20181']];

console.log(Object.fromEntries(arr));

If that’s not available, my previous solution was to map to an array of key-value objects and combine the objects by spreading into Object.assign:

Object.assign(...arr.map(([key, val]) => ({[key]: val})))
Sign up to request clarification or add additional context in comments.

7 Comments

Computed property names are also used in {[d[0]]: d[1]} :)
Object.assign.apply(null, arr.map(([key, val]) => { return { [key]: val } })) is a little easier to read and understand (when spread onto multiple lines).
What are the dots ...?
A similar one-liner (with reduce) which has the advantage of being more chainable: arr.reduce((obj, d) => Object.assign(obj, {[d[0]]: d[1]}), {})
Object.assign(...array.map( ([key, val]) => ({ [key]: val }) )) — An integration of @Toph's answer and @royhowie's comment.
|
62

Update June 2020

ECMAScript 2021 brings Object.fromEntries which does exactly the requirement:

const array =    [ [ 'cardType', 'iDEBIT' ],
      [ 'txnAmount', '17.64' ],
      [ 'txnId', '20181' ],
      [ 'txnType', 'Purchase' ],
      [ 'txnDate', '2015/08/13 21:50:04' ],
      [ 'respCode', '0' ],
      [ 'isoCode', '0' ],
      [ 'authCode', '' ],
      [ 'acquirerInvoice', '0' ],
      [ 'message', '' ],
      [ 'isComplete', 'true' ],
      [ 'isTimeout', 'false' ] ];
      
const obj = Object.fromEntries(array);
console.log(obj);

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries

This will do it:

const array =    [ [ 'cardType', 'iDEBIT' ],
      [ 'txnAmount', '17.64' ],
      [ 'txnId', '20181' ],
      [ 'txnType', 'Purchase' ],
      [ 'txnDate', '2015/08/13 21:50:04' ],
      [ 'respCode', '0' ],
      [ 'isoCode', '0' ],
      [ 'authCode', '' ],
      [ 'acquirerInvoice', '0' ],
      [ 'message', '' ],
      [ 'isComplete', 'true' ],
      [ 'isTimeout', 'false' ] ];
    
var obj = {};
array.forEach(function(data){
    obj[data[0]] = data[1]
});
console.log(obj);


2 Comments

Looks like new Map(array) solution below is more straightforward
Or even the answer with the "reduce"-method
46

A more idiomatic approach would be to use Array.prototype.reduce:

var arr = [
  [ 'cardType', 'iDEBIT' ],
  [ 'txnAmount', '17.64' ],
  [ 'txnId', '20181' ],
  [ 'txnType', 'Purchase' ],
  [ 'txnDate', '2015/08/13 21:50:04' ],
  [ 'respCode', '0' ],
  [ 'isoCode', '0' ],
  [ 'authCode', '' ],
  [ 'acquirerInvoice', '0' ],
  [ 'message', '' ],
  [ 'isComplete', 'true' ],
  [ 'isTimeout', 'false' ]
];

var obj = arr.reduce(function (o, currentArray) {
  var key = currentArray[0], value = currentArray[1]
  o[key] = value
  return o
}, {})

console.log(obj)
document.write(JSON.stringify(obj).split(',').join(',<br>'))

This is more visually appealing, when done with ES6 (rest parameters) syntax:

let obj = arr.reduce((o, [ key, value ]) => {
    o[key] = value
    return o
}, {})

2 Comments

cleaner way to avoid param reassign const obj = arr.reduce((obj, [ key, value ]) => { return { ...obj, [key]: value }; }, {});
Or even avoid the return statement: const obj = arr.reduce(obj, [key, value] => ({ ...obj, [key]: value }), {})
35

Use Map.

new Map(array);

The Map object holds key-value pairs and remembers the original insertion order of the keys. Any value (both objects and primitive values) may be used as either a key or a value.

This works because the type of your variable array is Array<[key,value]>. The Map constructor can be initialized with an array of arrays where the first element of the inner arrays is the key and the second is the value.

const array = [
  ['cardType', 'iDEBIT'],
  ['txnAmount', '17.64'],
  ['txnId', '20181'],
  ['txnType', 'Purchase'],
  ['txnDate', '2015/08/13 21:50:04'],
  ['respCode', '0'],
  ['isoCode', '0'],
  ['authCode', ''],
  ['acquirerInvoice', '0'],
  ['message', ''],
  ['isComplete', 'true'],
  ['isTimeout', 'false']
];

const obj = new Map(array);

console.log(obj.get('txnDate'));

9 Comments

Don't do this...it's too simple ^^
@Rick I'm confused here. I just tried this in the console: array = [['a', 1],['b','two'],['c', [3,3,3]]] and then obj = new Map(array);. However, obj.a and obj['a'] are both undefined. So how does this achieve the objective?
@RickViscomi -- Ok. Did not know about Map object. However, I would say that what most people are looking for is to get a regular JS object.
Not sure what most people are looking for, but the original question is looking for the value '2015/08/13 21:50:04' given the property txnDate and I think this is the most semantic way to do that.
@PA. typeof new Map() // "object" :)
|
15
arr.reduce((o, [key, value]) => ({...o, [key]: value}), {})

Comments

8

With Object.fromEntries, you can convert from Array to Object:

var entries = [
  ['cardType', 'iDEBIT'],
  ['txnAmount', '17.64'],
  ['txnId', '20181'],
  ['txnType', 'Purchase'],
  ['txnDate', '2015/08/13 21:50:04'],
  ['respCode', '0'],
  ['isoCode', '0'],
  ['authCode', ''],
  ['acquirerInvoice', '0'],
  ['message', ''],
  ['isComplete', 'true'],
  ['isTimeout', 'false']
];
var obj = Object.fromEntries(entries);
console.log(obj);

1 Comment

This is pretty cool, just be aware that as of writing this its status is: Draft. And the comment is: Initial definition in ECMAScript 2019.
3

use the following way to convert the array to an object easily.

var obj = {};
array.forEach(function(e){
   obj[e[0]] = e[1]
})

This will use the first element as the key and the second element as the value for each element.

Comments

3

ES5 Version using .reduce()

const object = array.reduce(function(accumulatingObject, [key, value]) {
  accumulatingObject[key] = value;
  return accumulatingObject;
}, {});

2 Comments

How do I use this? Sorry, javascript newb, not sure how to call this?
@PaulKenjora Where it says const object = array.reduce ... array is the name of the variable with the original array, and object is the name of the variable you are assigning the new value to. It's already being called, and assigning the value to a new variable object.
2

Short ES6 way with Airbnb code style

Exemple:

const obj = arr.reduce((prevObj, [key, value]) => ({ ...prevObj, [key]: value }), {});

Comments

2

The new JS API for this is Object.fromEntries(array of tuples), it works with raw arrays and/or Maps

1 Comment

Provide a code sample combining your suggestion with the code from the user that posted the question to make your answer more useful
1

easiest way to do it where array is of your JSON data :

var obj = {};
array.forEach(function(Data){
obj[Data[0]] = Data[1]
})

Comments

1

I much more recommend you to use ES6 with it's perfect Object.assign() method.

Object.assign({}, ...array.map(([ key, value ]) => ({ [key]: value })));

What happening here - Object.assign() do nothing but take key:value from donating object and puts pair in your result. In this case I'm using ... to split new array to multiply pairs (after map it looks like [{'cardType':'iDEBIT'}, ... ]). So in the end, new {} receives every key:property from each pair from mapped array.

Comments

1

You could do this easily using array reduce in ES6

In this example we create a reducer function and pass an object '{}' as initial value to the reduce function along with the reducer

const arr =    [ [ 'cardType', 'iDEBIT' ],
  [ 'txnAmount', '17.64' ],
  [ 'txnId', '20181' ],
  [ 'txnType', 'Purchase' ],
  [ 'txnDate', '2015/08/13 21:50:04' ],
  [ 'respCode', '0' ],
  [ 'isoCode', '0' ],
  [ 'authCode', '' ],
  [ 'acquirerInvoice', '0' ],
  [ 'message', '' ],
  [ 'isComplete', 'true' ],
  [ 'isTimeout', 'false' ] ];

const reducer = (obj, item) => {
  obj[item[0]] = item[1];
  return obj;
};

const result = arr.reduce(reducer, {});

console.log(result);

Comments

0
let obj ={'abc':123,'other':566};

// first way
let coll= Object.entries(obj).map(i=>Object.assign({'key':i[0],'value':i[1]}))

results: coll => 
0: {key: "abc", value: 123}
1: {key: "other", value: 566}

// second way
let coll2= new Map(Object.entries(obj))
results: coll2 =? 
//[[Entries]]
0: {"abc" => 123}
1: {"other" => 566}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.