1

I need to convert this kind of array:

const obj = [{
    name: 'firstLink',
    type: 'topic',
    id: 'ab75ca14-dc7c-4c3f-9115-7b1b94f88ff6',
    spacing: 1, // root
}, {
    name: 'secondLink',
    type: 'source',
    id: 'd93f154c-fb1f-4967-a70d-7d120cacfb05',
    spacing: 2, // child of previous object
}, {
    name: 'thirdLink',
    type: 'topic',
    id: '31b85921-c4af-48e5-81ae-7ce45f55df81',
    spacing: 1, // root
}]

Into this object:

const map = {
    'ab75ca14-dc7c-4c3f-9115-7b1b94f88ff6': {
        name: 'firstLink',
        type: 'topic',
        children: {
            'd93f154c-fb1f-4967-a70d-7d120cacfb05': {
                name: 'secondLink',
                type: 'source',
            }
        },
    },
    '31b85921-c4af-48e5-81ae-7ce45f55df81': {
        name: 'thirdLink',
        type: 'topic',
    }
}

There might be up to 10 nestings, may be more (defined as spacing in the array). How can i do that? I can use only pure js and lodash library.

5
  • What if there is spacing: 3 ? Commented Jun 6, 2016 at 11:54
  • then it should become a child of the last object with spacing: 2 Commented Jun 6, 2016 at 11:55
  • 1
    How do you know which child belongs to which parent? Is it guaranteed to be the previous array element? Commented Jun 6, 2016 at 12:02
  • I would advise you to refactor this using links like paranedId. Sou you don't need to order your array properly.. Just point parentid: 'ab75ca14-dc7c-4c3f-9115-7b1b94f88ff6' instead of spacing: 2 Commented Jun 6, 2016 at 12:36
  • @Max, it's impossible, because the array is actually interpreted lines of text. Commented Jun 6, 2016 at 13:47

1 Answer 1

1

You could use an array as reference to the inserted nested object.

var obj = [{ name: 'firstLink', type: 'topic', id: 'ab75ca14-dc7c-4c3f-9115-7b1b94f88ff6', spacing: 1, }, { name: 'secondLink', type: 'source', id: 'd93f154c-fb1f-4967-a70d-7d120cacfb05', spacing: 2, }, { name: 'thirdLink', type: 'topic', id: '31b85921-c4af-48e5-81ae-7ce45f55df81', spacing: 1, }],
    map = {};

obj.forEach(function (a) {
    this[a.spacing - 1][a.id] = { name: a.name, type: a.type, children: {}};
    this[a.spacing] = this[a.spacing - 1][a.id].children;
}, [map]);

console.log(map);

If you do not like empty children objects, you could use this proposal. It creates children properties only if necessary.

var obj = [{ name: 'firstLink', type: 'topic', id: 'ab75ca14-dc7c-4c3f-9115-7b1b94f88ff6', spacing: 1, }, { name: 'secondLink', type: 'source', id: 'd93f154c-fb1f-4967-a70d-7d120cacfb05', spacing: 2, }, { name: 'thirdLink', type: 'topic', id: '31b85921-c4af-48e5-81ae-7ce45f55df81', spacing: 1, }],
    map = {};

obj.forEach(function (a) {
    this[a.spacing - 1].children = this[a.spacing - 1].children || {};
    this[a.spacing - 1].children[a.id] = { name: a.name, type: a.type};
    this[a.spacing] = this[a.spacing - 1].children[a.id];
}, [map]);

map = map.children;
console.log(map);

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

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.