首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将对象数组转换为按值分组的数组

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

Stack Overflow用户
提问于 2020-03-03 03:32:12
回答 2查看 749关注 0票数 0

在fabric.js应用程序中,我的元素被分成几个组。

用户可以形成包含任意数量的元素的任意数量的组。

所附图像显示分组为三组的元素,每个元素显示其ID。

当用户完成创建组时,应用程序测量元素之间的距离,并将元素置于“父-子(Ren)”关系中。

这将产生一个对象数组:

代码语言:javascript
复制
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。

最后的结果应该是:

代码语言:javascript
复制
var groups = [
    [1, 2],
    [3, 4, 5, 6, 7],
    [8, 9, 10, 11, 12]
];
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-03-03 06:14:08

1)通过遍历元素来构建集合。对于每个元素,请检查父元素是否位于任何现有集合中。如果没有可用的集合,则创建该集。把孩子们加到片场里。

2)现在,我们有一组集合,可能有交叉集,需要合并。

3)将集合数组转换为数组数组。

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

代码语言:javascript
复制
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);

票数 1
EN

Stack Overflow用户

发布于 2020-03-20 10:00:10

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

  • 从父级开始,遍历其子级和其子级,直到堆栈为空。这是一个group.
  • Maintain,一个已访问的数组,以避免循环
  • 将组推到主数组(如果不是空的

)

代码语言:javascript
复制
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));

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60499687

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档