我有以下数组:
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'
}
];现在,我想要一个上面所有可能的数组组合的数组,有一个条件:一个组合不能包含两个具有相同引用的对象。
以下是所需组合的完整列表:
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下面是当前代码不能正常工作的地方:
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));发布于 2021-06-22 00:04:18
我的方法是:
我已经创建了一个递归解析函数(parseLevel),如果没有达到深度级别,它将查找与已经使用的ref不同的任何其他项。为了实现这一目标,我通过以下参数:
refs -已经使用了refs (过滤)、ids,acc -累加器、depth -当前深度levellevel -置换中所需的项目数。
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。
https://stackoverflow.com/questions/68075402
复制相似问题