如何在Javascript中创建数组元素的唯一组合?

如何在Javascript中创建数组元素的唯一组合?,javascript,Javascript,我有一个对象数组,我想在其中创建每个唯一的对象组合作为自己的数组。组合还需要包括不同数量的元素,并且无论提供的元素是什么,组合都应该有效。为了简化问题,假设我们有以下数组 让arr=[1,2,3] 这种情况下的结果如下: [1] [2] [3] [1, 2] [1, 3] [2, 3] [1, 2, 3] [ [ 1, 2, 3 ], [ 2, 3 ], [ 3 ], [ 1, 3 ], [ 1

我有一个对象数组,我想在其中创建每个唯一的对象组合作为自己的数组。组合还需要包括不同数量的元素,并且无论提供的元素是什么,组合都应该有效。为了简化问题,假设我们有以下数组

让arr=[1,2,3]

这种情况下的结果如下:

[1]
[2]
[3]
[1, 2]
[1, 3]
[2, 3]
[1, 2, 3]

    [ 
        [ 1, 2, 3 ], 
        [ 2, 3 ], 
        [ 3 ], 
        [ 1, 3 ], 
        [ 1, 2 ], 
        [ 2 ], 
        [ 1 ] 
    ]


我已经寻找了一个解决方案,并找到了一种使用笛卡尔积的方法,但这似乎并不适用于这种情况,因为我需要唯一的组合,并且不需要复制。如何使用Javascript解决此问题?

这可以在伪Javascript中递归定义:

function combos(arr) {
  if arr is empty
    return arr;
  else {
    result = [];
    // for every combination from the rest of the list
    for x in combos( arr.slice(1) ) {
       // get that combination w/o arr[0]
       result.push( x );  
       x.push( arr[0] );  
       // … and the combination w/ arr[0]   
       result.push( x );
    }
  }
}

我设法自己创建了一个解决方案。我创建了两个帮助函数,使问题更容易解决。第一个只是一个用于切换数组索引的函数,第二个是一个递归函数,让我们在每次递归调用时删除一个元素,并将结果和它自己的数组相加

通过对每个元素进行迭代,我可以得到数组的所有n长度组合。然后我移除第一个元素并重复该过程,直到元素用完。这将给我所有的解决方案,但他们将有重复

通过将它们升序排序并转换为字符串,我可以创建一组它们,这将创建唯一的字符串。最后一步是删除重复项,我最终得到所有的组合

let arr = [1, 2, 3];

let result = [];

while (arr.length !== 0) {
    for (let i = 0; i < arr.length; i++) {
        result = [...result, ...levelCombo(arr)];

        arr = switchIndex(arr, 0, i);
    }

    arr = arr.slice(1);
}

result = result.map(el => JSON.stringify(el.sort()));

let uniqueResult = [...new Set(result)].map(el => JSON.parse(el));

console.log(uniqueResult);

function switchIndex(arr, a, b) {
    let val1 = arr[a];
    let val2 = arr[b];

    arr[a] = val2;
    arr[b] = val1;

    return arr;
}

function levelCombo(arr) {
    let result = [];

    if (arr.length === 0) {
        return [];
    }

    for (let i = 0; i < arr.length; i++) {
        result.push(arr[i]);
    }

    result = [result, ...levelCombo(arr.slice(1))];

    return result;
}

您可以采用递归方法并返回一个项目数组

函数组合(数组){
函数iter(索引,温度=[])){
如果(!index--)返回;
iter(指数、温度);
push(temp=[array[index],…temp]);
iter(指数、温度);
}
var结果=[];
iter(阵列长度);
返回结果;
}
组合([1,2,3]).forEach(a=>console.log(a.join(“”))

.as控制台包装{max height:100%!important;top:0;}
组合和排列可以通过搜索web(等等)很好地覆盖,可以手动或通过库完成。请看这一页;至少你应该发布到目前为止尝试了什么,以及(具体地)它是如何不起作用的。这不是我的家庭作业。我正在处理一个我以前从未面对过的问题,似乎无法找到最佳解决方案。当然,我对算法不是很有经验,所以我恳请您为我指出正确的方向。@gogibogi4“最优”是不可行的;优化了什么?你有什么具体问题?这是一个研究得很好的主题,有很多实现,有各种各样的折衷,到处都有文档记录。我想避免使用太多的迭代,因为这会导致糟糕的性能。你能给我提供一个链接,让我可以对这个问题进行更多的研究吗?当然,一定还有一种算法,我可以在类似的情况下使用。@gogibogi4这是我认为你应该能够自己研究的东西——这就是为什么我要问具体的原因,因为你自己的研究肯定有一些原因。这也是为什么我要问你已经尝试过的东西,为什么它不能满足你的任何目标。