1

I have an array that looks like this

var myArray = [
    ['a', 1],
    ['b', 2],
    ['c', 3]
]

I want to convert it into an object, it should be equal to below:

var myObj = {
    'a' : 1,
    'b' : 2,
    'c' : 3
}

What is the easier and safer (if unexpected input comes) way to go about it?

Update: To elaborate more on 'safer', sometimes I might get different input like

var myArray = [
    ['a', 1],
    ['b', 2],
    ['c', 3, 4, 5]
]

or

var myArray = [
    ['a', 1],
    ['b', 2],
    ['c', 3],
    ['d']
]

Regardless myObj should be equal to:

var myObj = {
    'first-key' : 'firts-value'
}

or if 2nd element is not available in sub-array

var myObj = {
    'first-key' : ''
}
8
  • like this Commented Nov 4, 2016 at 15:22
  • @KevinKloet Elements in my array are arrays themselves. Commented Nov 4, 2016 at 15:24
  • 1
    Can you clarify what you mean by unexpected input? Strikes me as a very important requirement if it means you need to be able to handle things like myArray not being an array or somesuch. Commented Nov 4, 2016 at 15:27
  • @tmslnz Subarrays might have 1 element or sometimes more than 2. But I'm only interested in capturing first 2, if it has 1 element, value of key can be just '' Commented Nov 4, 2016 at 15:28
  • @sdkks ok. And do those arrays need to be flattened or c: [1,2,3,4,5,…] is an acceptable output? Commented Nov 4, 2016 at 15:29

4 Answers 4

2

You can do this with reduce()

var myArray = [
  ['a', 1],
  ['b', 2],
  ['c', 3]
]

var result = myArray.reduce((r, e) => {
  r[e[0]] = e[1];
  return r;
} , {});

console.log(result)

Update: for cases where there is just one element in array (return '') or more then two (return array with rest of elements).

var myArray = [
  ['a', 1],
  ['b', 2],
  ['c', 3, 3 ,1],
  ['d']
]

var result = myArray.reduce((r, e) => {
  r[e[0]] = (e[1]) ? ((e.length > 2) ? e.slice(1) : e[1]) : '';
  return r;
} , {});

console.log(result)

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

4 Comments

This does not handle "unexpected input". It does not ensure that each property you are iterating over is an indexed array
@NenadVracar can you explain your updated answer, what does [...e] do?
Still doesn't account for myArray being heterogeneous, nor non-string/non-integer elements of each sub-array
@sdkks That is spread operator but actually we don't need that.
0
var myArray = [
    ['a', 1],
    ['b', 2],
    ['c', 3]
];

var myObj = {};

myArray.forEach(function(element){
    myObj[element[0]] = element[1];
})

1 Comment

This code makes a lot of assumptions - and does not handle "unexpected input" as the OP asked.
0

just use a forEach to populate myObj :

var myArray = [
    ['a', 1],
    ['b', 2],
    ['c', 3]
];
var myObj = {};
myArray.forEach(x => myObj[x[0]]=x[1]);
console.log(myObj);

Comments

-1

None of the other answers handle unexpected input... The way to do this is with .reduce() and type checking.

var myArray = [
  [[1, 2, 3], 'a'], // [1] is valid property name, [0] valid value
  ['b', 2, 5, 2], // [0] is valid property name, [1] valid value
  ['c', undefined], // [0] is valid property name, [1] invalid value
  { prop1: "123" }, // Invalid - is not an array
  undefined, // Invalid - is not an array
  123, // Invalid - is not an array
  [undefined, 'd'], // [1] is valid property name, [0] valid value
  ['e'] // [0] is valid property name, [1] does not exist
];

function convertArrToObj(arr) {
  // check to ensure that parent is actually an array
  if (isArray(arr)) {
    return arr.reduce(function(obj, curr) {
      // check to ensure each child is an array with length > 0
      if (isArray(curr) && curr.length > 0) {
        // if array.length > 1, we are interested in [0] and [1]
        if (curr.length > 1) {
          // check if [0] is valid property name
          if (typeof curr[0] === "string" || typeof curr[0] === "number") {
            // if so, use [0] as key, and [1] as value
            obj[curr[0]] = curr[1] || ""
          } 
          // if not, check if [1] is a valid property name
          else if (typeof curr[1] === "string" || typeof curr[1] === "number") {
            // if so, use [1] as key, and [0] as value
            obj[curr[1]] = curr[0] || ""
          }
          // if no valid property names found, do nothing
        } else {
          // if array.length === 1, check if the one element is
          // a valid property name. 
          if (typeof curr[0] === "string" || typeof curr[0] === "number") {
            // If so, add it and use "" as value
            obj[curr[0]] = "";
          }
        }
      }
      // return updated object for next iteration
      return obj
    }, {});
  }
}

function isArray(val) {
  return val === Object(val) && Object.prototype.toString.call(val) === '[object Array]';
}

console.log(convertArrToObj(myArray));

4 Comments

It will take me a few days to digest this. Many lessons here.
@sdkks I will go through and comment this so you can see exactly what is happening
@sdkks Check the updated answer with comments explaining what every line does
Thanks now makes more sense. My expectation of 'unexpected' has not had a spectrum this broad.

Your Answer

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