首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于对象数组获取组合数组

基于对象数组获取组合数组
EN

Stack Overflow用户
提问于 2021-06-21 22:21:34
回答 1查看 69关注 0票数 1

我有以下数组:

代码语言:javascript
复制
const arr = [
  {
    _id: '60c936bca0bd431287ae698b',
    name: 'Markets',
    referential: '60c936bca0bd431287ae6988'
  },
  {
    _id: '60c93b17a0bd431287ae69a0',
    name: 'eRetailers',
    referential: '60c93b17a0bd431287ae699f'
  },
  {
    _id: '60d0a30d303ebd2a19d6fb4d',
    name: 'Products',
    referential: '60d0a30d303ebd2a19d6fb4b'
  },
  {
    _id: '60c936bca0bd431287ae6989',
    name: 'Regions',
    referential: '60c936bca0bd431287ae6988'
  },
  {
    _id: '60d0a30d303ebd2a19d6fb4c',
    name: 'Segments',
    referential: '60d0a30d303ebd2a19d6fb4b'
  }
];

现在,我想要一个上面所有可能的数组组合的数组,有一个条件:一个组合不能包含两个具有相同引用的对象。

以下是所需组合的完整列表:

代码语言:javascript
复制
Aggregations level 1 :
Products
Segments
Markets
Regions
eRetailers

Aggregations level 2 :
Products/Markets
Products/Regions
Products/eRetailers
Segments/Markets
Segments/Regions
Segments/eRetailers
Markets/Products
Markets/Segments
Markets/eRetailers
Regions/eRetailers
Regions/Products
Regions/Segments
eRetailers/Markets
eRetailers/Regions
eRetailers/Products
eRetailers/Segments

Aggregations Niveau 3 :
Products/Regions/eRetailers
Products/eRetailers/Regions
Segments/Markets/eRetailers
Segments/eRetailers/Markets
Segments/Regions/eRetailers
Segments/eRetailers/Regions
Markets/eRetailers/Segments
Markets/Segments/eRetailers
Regions/Products/eRetailers
Regions/eRetailers/products
Regions/Segments/eRetailers
Regions/eRetailers/PSegments
eRetailers/Regions/Products
eRetailers/Products/Regions
eRetailers/Markets/Segments
eRetailers/Segments/Markets
eRetailers/Regions/Segments
eRetailers/Segments/Regions

下面是当前代码不能正常工作的地方:

代码语言:javascript
复制
function combinator (s) {
   list_of_strings = new Array();
   for(i=0;i<s.length;i++) {
       for(j=i+1;j<s.length+1;j++) {
           list_of_strings.push(s.slice(i, j));
       }
   }
   return list_of_strings;
}

console.log(combinator(arr));
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-06-22 00:04:18

我的方法是:

我已经创建了一个递归解析函数(parseLevel),如果没有达到深度级别,它将查找与已经使用的ref不同的任何其他项。为了实现这一目标,我通过以下参数:

  • refs -已经使用了refs (过滤)、
  • ids
  • acc -累加器、
  • depth -当前深度level
  • level -置换

中所需的项目数。

代码语言:javascript
复制
const arr = [{
    _id: '60c936bca0bd431287ae698b',
    name: 'Markets',
    referential: '60c936bca0bd431287ae6988'
  },
  {
    _id: '60c93b17a0bd431287ae69a0',
    name: 'eRetailers',
    referential: '60c93b17a0bd431287ae699f'
  },
  {
    _id: '60d0a30d303ebd2a19d6fb4d',
    name: 'Products',
    referential: '60d0a30d303ebd2a19d6fb4b'
  },
  {
    _id: '60c936bca0bd431287ae6989',
    name: 'Regions',
    referential: '60c936bca0bd431287ae6988'
  },
  {
    _id: '60d0a30d303ebd2a19d6fb4c',
    name: 'Segments',
    referential: '60d0a30d303ebd2a19d6fb4b'
  }
];
const refIds = [...new Set(arr.map(({referential}) => referential))].map(ref => ({
  ref,
  _ids: arr.filter(({referential}) => referential === ref).map(({_id}) => _id)
}));

function getPermutations(level) {
  return refIds.reduce((acc, {ref, _ids}) => {
    _ids
      .forEach(id => parseLevel({
        depth: 1,
        level,
        refs: [ref],
        ids: [id],
        acc
      }));
    return acc;
  }, [])
}

function parseLevel({depth, level, refs, ids, acc}) {
  if (depth === level) {
    acc.push(ids.map(id => getItemName(id)).join('/'))
  } else {
    refIds
      .filter(({ref}) => !refs.includes(ref))
      .forEach(({ref, _ids}) => _ids
        .forEach(id => parseLevel({
          depth: depth + 1,
          level,
          refs: [...refs, ref],
          ids: [...ids, id],
          acc
        }))
      );
  }
}

function getItemName(id) {
  return arr.find(({_id}) => _id === id).name
}

console.log(Object.assign({}, 
  ...[1, 2, 3, 4].map(i => ({ [i + ' permutations']: getPermutations(i) })),
  { refIds }
))

因为需求是创建具有唯一ref的项的组合,所以我首先创建一个包含所有不同refs:refIds的数组。在每个元素中,我都会将所有具有该ids的元素放在ref中。这一步并不是真正必要的,但它确保我们不会迭代那些无论如何都会被排除的项(因为它们具有相同的ref)。

然后,我开始创建结果,方法是遍历每个refId元素的每个refId,将其id放入ids中(将其ref放入refs中),然后运行parseLevel,以查找没有在refs中存在ref的任何元素。如果它找到了一个,它也会这样做:把它的id发布到ids,把它的ref发布到refs。然后它再次运行parseLevel

每次运行时,它首先检查是否达到了所需的深度level。如果是这样的话,它会将ids转换为名称,因为这正是我们想要显示的。

这里明显的优点是递归性:这意味着这将适用于任意数量的不同refs (因此可以使用任意数量的level)。我认为理所当然的唯一条件是每个元素都有一个唯一的_id

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

https://stackoverflow.com/questions/68075402

复制
相关文章

相似问题

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