Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
434 views
in Technique[技术] by (71.8m points)

Javascript special sorting array of objects by value and parent

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

question from:https://stackoverflow.com/questions/65829291/javascript-special-sorting-array-of-objects-by-value-and-parent

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...