1

I'm trying to create a function that will convert an array like this:

[['a', 1], ['b', 2], ['c', [['d', 4]]]]

Into an object like this:

{ a: 1, b: 2, c: { d: 4 } }

So far I just have a function that converts a regular array to regular object, and I'm getting the hang of recursion I'm just not sure how to implement it in such a case. Here is the function that I am working with:

const deepArrayToObject = function(arr) {
  let obj = {};
  if (arr !== []) {
    return obj;
  }
  for (let i = 0; i < arr.length; i++) {
    for (let j = 0; j < arr[i].length; j++) {
      let key = arr[i][0];
      let value = arr[i][1];
      obj[key] = value;
    }
  }
  return obj;
};

I appreciate the feedback.

1
  • I just noticed that you have some arrays "double wrapped", like this: [['d', 4]]. Is that intentional? Commented Aug 10, 2020 at 3:13

2 Answers 2

2

The trick would be to check whether the value of a given property is an array. If it is, call the function again on the value, otherwise use the value as is.

Here's a version using Array.prototype.reduce.

const a = [['a', 1], ['b', 2], ['c', [['d', 4]]]];

const o = arrayToObject(a);
console.log(o);

function arrayToObject(a) {
  return a.reduce((o, [k, v]) => Object.assign(o, {
   [k]: Array.isArray(v) ? arrayToObject(v) : v,
  }), {});
}

The Object.assign function allows you to append the properties of one or more objects onto a target object.

In the example below, the properties of object b will be appended to object a and a returned. Therefore a and c are the same object.

const a = { a: 'A' };
const b = { b: 'B' };
const c = Object.assign(a, b);

console.log(a, c, a === c);

The ternary operator is a short-hand if statement. In the function it is checking if v is an array. If it is, the array value is passed to the function again initiating the recursive call.

It could be rewritten:

if (Array.isArray(v)) {
    return arrayToObject(v);
} else {
    return v;
}
Sign up to request clarification or add additional context in comments.

5 Comments

A minor note - here a new object is created at each iteration of reduce. More efficient approach would be to modify it in place. (o, [k, v]_ => { o[k] = ...; return o; }
Object.assign does actually return the target object specified as the first parameter, so it is modifying the existing object rather than creating a new object each time. See the docs for more information. Here's a fiddle showing this.
No worries. I did have to double check to make sure :)
Awesome, thanks for the suggestion, works great! I had a feeling I might have needed the Array.isarray. Can you break down the use of object.assign for me with the use of the ternary operator? I think I get it but it would be nice to have a deeper understanding of it (have also checked MDN on it as it is relatively new to me). Thanks again.
I've added an extended explanation. Does that make more sense?
1

You need only one loop, and for the value, check to see which you have, and if it's an array, do the recursion.

const deepArrayToObject = function(arr) {
  let obj = {};

  // This does nothing useful
  //  if (arr !== []) {
  //    return obj;
  //  }

  for (let i = 0; i < arr.length; i++) {
    let key = arr[i][0];
    let value = arr[i][1];
    
    if (Array.isArray(value)) {
      obj[key] = deepArrayToObject(value);
    } else {
      obj[key] = value;
    }
  }
  return obj;
};

const a = [['a', 1], ['b', 2], ['c', [['d', 4]]]];

const res = deepArrayToObject(a);

console.log(res);

1 Comment

thanks slappy! works perfect and easy for my beginner mind to grasp :). I had a feeling I was just a few small steps away. I forgot to remove that conditional that you commented out as I just started working on it after a break and added that as a start, then thought that wasn't the right way, I should get some help! thanks again.

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.