Well, I have an array with objects where some elements depends of others elements.
So, I need to order it by importance (dependency of parent) to store this on a database and replace all the children's parent
property by the respective parent id
.
Example of the array:
[
{
"id": 1,
"email": "a@b.com", // unique
"parent": "c@b.com" // is nullable
},
{
"id": 2,
"email": "b@b.com",
"parent": null
},
{
"id": 3,
"email": "c@b.com",
"parent": "b@b.com"
},
{
"id": 4,
"email": "d@b.com",
"parent": "a@b.com"
},
...
]
Graphical example of dependency:
Expected result: Ordered by dependency (parent):
[
{
"id": 2,
"email": "b@b.com",
"parent": null
},
{
"id": 3,
"email": "c@b.com",
"parent": 2
},
{
"id": 1,
"email": "a@b.com",
"parent": 3
},
{
"id": 4,
"email": "d@b.com",
"parent": 1
},
...
]
To set respective parent id
I'm using (but it no ordering by parent level: parent, children, grandchildren...):
let users = [
{
"id": 1,
"email": "a@b.com", // unique
"parent": "c@b.com" // is nullable
},
{
"id": 2,
"email": "b@b.com",
"parent": null
},
{
"id": 3,
"email": "c@b.com",
"parent": "b@b.com"
},
{
"id": 4,
"email": "d@b.com",
"parent": "a@b.com"
}
];
users = users.map(user => {
user.parent = _.findIndex(users, i => user.parent === i.email);
return user;
});
P.S:
In this case, the importance
concept refers to parent
level.
So, First I need the parents, then the children, grandchildren, and so on...
I am sorry if this thread is poor in explanations, if you have doubts, I will look for the best way to express the idea.
I will approach this by first generating a new input with the replacement of parent email
by the parent id
and a new property of the node level related to the tree they belong. Then we can sort the nodes by this level
property, and on equal level
we sort by the id
.
const input = [
{"id": 1, "email": "a@b.com", "parent": "c@b.com"},
{"id": 2, "email": "b@b.com", "parent": null},
{"id": 3, "email": "c@b.com", "parent": "b@b.com"},
{"id": 4, "email": "d@b.com", "parent": "a@b.com"},
{"id": 5, "email": "x@b.com", "parent": "b@b.com"},
{"id": 6, "email": "z@b.com", "parent": "x@b.com"},
{"id": 7, "email": "y@b.com", "parent": null},
{"id": 8, "email": "m@b.com", "parent": "y@b.com"}
];
const findParent = (mail) => input.find(x => x.email === mail);
const getLevel = (mail, lvl) =>
{
return mail ? getLevel(findParent(mail).parent, lvl + 1) : lvl;
}
let newInput = input.map(({id, email, parent}) =>
{
return {
id: id,
email: email,
parent: findParent(parent) ? findParent(parent).id : null,
lvl: getLevel(parent, 0)
};
});
let sortedInput = newInput.sort((a, b) =>
{
return (a.lvl - b.lvl) ? a.lvl - b.lvl : a.id - b.id;
});
console.log(sortedInput);