0

I would like to convert an array of objects that looks like:

const children = [
  { name: c1, parent: p1, draw_order: 1 },
  { name: c2, parent: p2, draw_order: 2 },
  { name: c3, parent: p2, draw_order: 4 },
  { name: c4, parent: p1, draw_order: 3 },
  { name: c5, parent: p3, draw_order: 1 },
];

1. I want to make a new array that contains parent object like:

const parents = [
  { name:p1, draw_order: 1, children: [...] },
  { name:p2, draw_order: 2, children: [...] },
  { name:p3, draw_order: 1, children: [...] },
]

The draw_order of parent Object should be equal to the lowest value of the children's draw_order values.

Something like:

const parents = [];

children.forEach(c => {
  const parent = parents.find(p => p.name === c.name);
  parent ? parents.children.push(c) : parents.push({name: c.parent, children:[c})
})

parents.forEach(p => {
  const drawOrder = Math.min(...p.children.map(c => c.drawOrder));
  p.draw_order = drawOrder;
})

2. The parents now have repeated draw_order - 1, 2, 1; I Would like to Update it to:

1 => 1, 2 => 3, 1 => 2

if the values are: [1, 3, 4, 4, 1, 3, 2]

1 => 1
3 => 4
4 => 6
4 => 7
1 => 2
3 => 5
2 => 3

The final result should be:

const parents = [
  { name:p1, draw_order: 1, children: [...] },
  { name:p2, draw_order: 3, children: [...] },
  { name:p3, draw_order: 2, children: [...] },
]

Just for checking if we have:

const children = [
  { name: c1, parent: p1, draw_order: 1 },
  { name: c2, parent: p8, draw_order: 2 },
  { name: c3, parent: p2, draw_order: 4 },
  { name: c4, parent: p1, draw_order: 3 },
  { name: c5, parent: p4, draw_order: 3 },
  { name: c6, parent: p4, draw_order: 9 },
  { name: c7, parent: p3, draw_order: 1 },
];

The outPuts should be

const parents = [
  { name:p1, draw_order: 1, children: [...] },
  { name:p2, draw_order: 5, children: [...] },
  { name:p3, draw_order: 2, children: [...] },
  { name:p4, draw_order: 4, children: [...] },
  { name:p8, draw_order: 3, children: [...] },
]

Thanks

2 Answers 2

1

Reduce the children to a Map of parents by parent. If a parent already exists in the Map, store the child in the children's array, and replace the draw_order if needed.

Whenever a new parent is encountered, set an object with the parent's name, base draw_order (the current child's), and a children array with the current child. Use the parent as the Map's key.

Convert the Map's values to an array with Array.from().

const children = [{"name":"c1","parent":"p1","draw_order":1},{"name":"c2","parent":"p2","draw_order":2},{"name":"c3","parent":"p2","draw_order":4},{"name":"c4","parent":"p1","draw_order":3},{"name":"c5","parent":"p3","draw_order":1}];

const result = Array.from(children.reduce((acc, o) => {
  if(acc.has(o.parent)) {
    const parent = acc.get(o.parent);

    parent.children.push(o);

    parent.draw_order = Math.min(o.draw_order, parent.draw_order);
  } else {
    acc.set(o.parent, { 
      name: o.parent, 
      draw_order: o.draw_order,
      children: [o] 
    });
  }

  return acc;
}, new Map()).values());

console.log(result);

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

Comments

1

You could create a new order by collecting all values and remap new order.

const
    array = [1, 3, 4, 4, 1, 3, 2],
    result = array
        .reduce((r, v, i) => ((r[v] ??= []).push(i), r), [])
        .flat()
        .reduce((v => (r, i) => (r[i] = v++, r))(1), []);

console.log(...result);

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.