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]));

asked Jun 20, 2020 at 0:07
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);

answered Jun 20, 2020 at 0:18
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));

answered Jun 20, 2020 at 0:13

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));

answered Jun 20, 2020 at 0:16

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)

answered Jul 5, 2020 at 17:54

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.