7

I have an array [1, 2, 3] and I want to transfer it to object with nested parent-child objects's series like this :

{ value: 1, rest: { value: 2, rest: { value: 3, rest: null } } 

If I have an array [1, 2, 3, 4] the result will be like this :

{ value: 1, rest: { value: 2, rest: { value: 3, rest: { value:4, rest:null } } 

The best effort of me is this snippet of code :

const arrayToList = (array) => {
  let list = { value: null, rest: null };
  for (let e of array) {
    array.indexOf(e) === 0 && (list.value = e);
    array.indexOf(e) >= 1 && (list.rest = { value: e });
  }
  return list;
};
console.log(arrayToList([1, 2, 3]));

3
  • did you see my answer ? if there's something went wrong with it please let me know Commented Aug 14, 2020 at 20:14
  • 1
    Yes. It works well. Commented Aug 14, 2020 at 20:43
  • Thank you my bro ! Commented Aug 14, 2020 at 20:54

4 Answers 4

8

You can use reduceRight like so:

let obj = arr.reduceRight((rest, value) => ({ value, rest }), null);

It starts building the object from the inside out; it starts by creating the innermost object and then it uses that object as the rest property for the next outer object and so on until there are no more items in the array.

Demo:

let obj = [1, 2, 3, 4].reduceRight((rest, value) => ({ value, rest }), null);

console.log(obj);

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

3 Comments

I'd just say: Wonderful! because I hate writing functions with if-else.
@MenaiAlaEddine-Aladdin Thanks! The trick here is to start from the last item of the array and building the object from the inside out. Even if you use a simple for loop instead of reduceRight, if you start from the last item, you won't need if-else.
@MenaiAlaEddine-Aladdin ... like this jsfiddle.net/gd94npqf which is pretty much exactly what reduceRight is doing
1

You can create such object by running below recursive function:

let arr = [1, 2, 3, 4];

let transform = (arr, obj) => {
   if(arr.length === 0){
      return obj;
   } else {
      let last = arr[arr.length - 1];
      let newArr = arr.slice(0, arr.length - 1);
      
      return transform(newArr, { value: last, rest: obj || null })
   }
};

console.log(transform(arr));

1 Comment

I want to avoid recursive functions for long-time execution if the array will be big.
1

Use a recursive function:

let array = [1, 2, 3];

function arrayToL(array) {
  let el = array.splice(0, 1)[0];
  let rtn = {
    value: el
  }

  rtn.rest = (array.length > 0) ? arrayToL(array) : null;

  return rtn;
}

console.log(arrayToL(array));

Comments

1

I suggest another solution using the spread operator and reversing the array and start building object from the array end :

let arr = [1, 2, 4, 5]

let obj = {} //object to be built

arr.slice().reverse().forEach(item => { //i used the slice method 
  //in order to avoid mutating
  //the original variable
  obj = { ...obj,
    ...{
      value: item,
      rest: obj
    }
  };

})

console.log(obj)

Comments

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.