2

I have a JavaScript array of objects, like this:

var start = [{
  name: 'example name',
  nextItem: {}
},
{
  name: 'example name 2',
  nextItem: {}
},
{
  name: 'example name 3',
  nextItem: {}
}];

I want to convert this array into a single nested object, where the inner nextItem object of the first array item contains the whole object of the next array item. For example:

var output = {
  name: 'example name',
  nextItem: {
    name: 'example name 2',
    nextItem: {
      name: 'example name 3',
      nextItem: {}
    }
  }
}

Any ideas?

9
  • 3
    Have you already tried something, and do you stuck somewhere? Commented Aug 16, 2017 at 10:33
  • 3
    I'm voting to close this question as off-topic because the question shows input and expected output format but does not show any sign of effort. This is a requirement and not a problem statement. Commented Aug 16, 2017 at 10:40
  • 2
    @Rajesh - This question is perfectly valid. You only need to show attempted code if you're asking what is wrong with it. This is both a specific programming problem and a practical, answerable problem that is unique to software development. See here... stackoverflow.com/help/on-topic Commented Aug 16, 2017 at 10:49
  • 2
    @Rejesh if SO were so strict, 80% of questions would be closed. We should push on the OP like I did im my first comment, but close because the guy don't know where to start is a bit extreme Commented Aug 16, 2017 at 10:54
  • 1
    @Rajesh - please read the link I gave you. It explains why this question is perfectly valid. Commented Aug 16, 2017 at 12:46

6 Answers 6

2

Could be done with a recursive function:

function nestItems(items) {
  var currentItem = items[0];
  if (!currentItem) return {};

  return {
     name: currentItem.name,
     nextItem: nestItems(items.slice(1))
  };
}


nestItems(start);
Sign up to request clarification or add additional context in comments.

1 Comment

Should we really answer such question that do not show any sign of effort?
2

You can use Array.prototype.reduceRight().

Code:

var start = [{name: 'example name',nextItem: {}},{name: 'example name 2',nextItem: {}},{name: 'example name 3',nextItem: {}}],
    output  = start.reduceRight(function (a, c) {
      return {
        name: c.name, 
        nextItem: a
      }; 
    });

console.log(output );

Updated based on comment from @NinaScholz

4 Comments

hm reverse? really? why not use reduceRight?
Code is first place for humans, so readability is on 1st place
Yeah, its not fair ik, the solution it self is ok, so upvote
I am totally agree that code should be in first place for humans. I have edited to make it more readable and better indented.. Thank you for your comments
0

Try this :

var start = [{
  name: 'example name',
  nextItem: {}
},
{
  name: 'example name 2',
  nextItem: {}
},
{
  name: 'example name 3',
  nextItem: {}
}];

function concat(start) {
    var output = start[0];
    temp = output;
    for(i = 1;i < start.length;i ++) {
        temp.nextItem = start[i];
        temp = temp.nextItem;
    }
    return output;
}

console.log(concat(start));

Comments

0

There may be a more graceful way of doing it, but this will do the trick. (The trick being to start at the bottom and work your way up).

var start = [{
  name: 'example name',
  nextItem: {}
},
{
  name: 'example name 2',
  nextItem: {}
},
{
  name: 'example name 3',
  nextItem: {}
}];

var output = {};

for (var i = start.length; i > 0; i--) {
  output = { name: start[i - 1].name, nextItem: output };
}

console.log(output);

2 Comments

Should we really answer such question that do not show any sign of effort?
@Rajesh - The question is perfectly valid.
0

You can use reduce on the array to add the objects:

function appendRec(obj, newObj) {
    if (obj || obj.nextItem === {}) obj.nextItem = newObj
    else appendRec(obj.nextItem, newObj)
    return obj
}

var output = start.reduce((acc, obj) => {
    return appendRec(acc, obj)
}, { nextItem: { } }).nextItem;

3 Comments

This will produce a single object with a single nextItem, which is the last one in the list..
Correct, please prefer Yosvel Quinteros answer.
I would prefer mine, is most elegant IMO :D
0

You could use and take the returned accumulator as target for the nested object without mutating the original array.

var start = [{ name: 'example name', nextItem: {} }, { name: 'example name 2', nextItem: {} }, { name: 'example name 3', nextItem: {} }],
    result = {};

start.reduce(function (o, a) {
    o.name = a.name;
    o.nextItem = {};
    return o.nextItem;
}, result);

console.log(result);
console.log(start);

ES6 with mutating the original array.

var start = [{ name: 'example name', nextItem: {} }, { name: 'example name 2', nextItem: {} }, { name: 'example name 3', nextItem: {} }],
    result = {};

start.reduce(function (o, a) {
    Object.assign(o, a);
    return o.nextItem;
}, result);

console.log(result);
console.log(start);

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.