繁体   English   中英

将对象数组转换为按值分组的数组数组

[英]Convert array of objects to array of arrays grouped by values

在fabric.js 应用程序中,我将元素分为几组。
用户可以形成包含任意数量元素的任意数量的组。
附加的图像显示了分为三组的元素,每个元素都显示了它的 ID。

画布元素

当用户创建完组后,应用程序会测量元素之间的距离,并将元素置于“父 - 子(人)”关系中。
这会产生一个对象数组:

var elements = [
    { "parent": 1, "children": [ 2 ] },
    { "parent": 2, "children": [ 1 ] },
    { "parent": 3, "children": [ 7 ] },
    { "parent": 4, "children": [ 5, 6 ] },
    { "parent": 5, "children": [ 4, 6, 7 ] },
    { "parent": 6, "children": [ 4, 5 ] },
    { "parent": 7, "children": [ 3, 5 ] },
    { "parent": 8, "children": [ 9 ] },
    { "parent": 9, "children": [ 8, 11 ] },
    { "parent": 10, "children": [ 11, 12 ] },
    { "parent": 11, "children": [ 9, 10 ] },
    { "parent": 12, "children": [ 10 ] }
];

组中的每个元素都是距离它最近的元素的父元素,但同时它也是距离它最近的元素的子元素。
在此示例中,如何从“元素”数组中获取包含三个子数组的数组?
每个结果子数组应包含仅在该组中的元素的 ID。
最终结果应该是:

var groups = [
    [1, 2],
    [3, 4, 5, 6, 7],
    [8, 9, 10, 11, 12]
];

1)通过遍历元素来构建集合。 对于每个元素,检查 parent 是否在任何现有集合中。 如果没有可用的集合,则创建该集合。 将孩子添加到集合中。
2)现在,我们有一组集合,并且可能有相交的集合,需要合并。
3) 将集合数组转换为数组数组。

PS:我认为合并的第 2 步可以合并到第 1 步本身中。

 var elements = [ { parent: 1, children: [2] }, { parent: 2, children: [1] }, { parent: 3, children: [7] }, { parent: 4, children: [5, 6] }, { parent: 5, children: [4, 6, 7] }, { parent: 6, children: [4, 5] }, { parent: 7, children: [3, 5] }, { parent: 8, children: [9] }, { parent: 9, children: [8, 11] }, { parent: 10, children: [11, 12] }, { parent: 11, children: [9, 10] }, { parent: 12, children: [10] } ]; const arrSets = []; elements.forEach(({ parent, children }) => { let set = arrSets.find(set => set.has(parent)); if (!set) { set = new Set(); set.add(parent); arrSets.push(set); } children.forEach(x => set.add(x)); }); const resSets = []; arrSets.forEach(set => { let curr = resSets.find(dat => [...set].some(x => dat.has(x))); if (!curr) { curr = new Set(); resSets.push(curr); } [...set].forEach(x => curr.add(x)); }); const arr = resSets.map(set => [...set]); console.log(arr);

这是使用堆栈解决问题的另一种方法。

  • 从父母开始,遍历它的孩子和他们的孩子,直到堆栈为空。 这是一组。
  • 维护一个访问过的数组以避免循环
  • 如果组不为空,则将组推送到主数组

 function findGrops(elements) { const eleMap = {}; // build a parent => children map elements.forEach( e => { eleMap[e.parent] = e.children; }); const groups = []; const visited = {}; // iterate in a depth first way // parent -> children -> their children until empty Object.keys(eleMap).forEach( k => { let grp = []; let stk = [k]; //parseInt(k,10) to avoid the quotes while( stk.length > 0) { let x = stk.pop(); if (!(x in visited)) { grp.push(x); visited[x] = true; // add children to the stack stk = stk.concat(eleMap[x]); } } // push to groups array grp.length && groups.push(grp); }); return groups; } const input = [ { "parent": 1, "children": [ 2 ] }, { "parent": 2, "children": [ 1 ] }, { "parent": 3, "children": [ 7 ] }, { "parent": 4, "children": [ 5, 6 ] }, { "parent": 5, "children": [ 4, 6, 7 ] }, { "parent": 6, "children": [ 4, 5 ] }, { "parent": 7, "children": [ 3, 5 ] }, { "parent": 8, "children": [ 9 ] }, { "parent": 9, "children": [ 8, 11 ] }, { "parent": 10, "children": [ 11, 12 ] }, { "parent": 11, "children": [ 9, 10 ] }, { "parent": 12, "children": [ 10 ] } ]; console.log('result:', findGrops(input));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM