Javascript 在循环中查找所有选项组合

Javascript 在循环中查找所有选项组合,javascript,arrays,loops,Javascript,Arrays,Loops,我正在寻找一种最好的方法来循环一系列的选项,以确保我找到了所有可用的选项 我已经创建了一个特性,它允许客户端构建基本上是相互层叠的其他图像的图像。这些其他图像被分成不同的组。他们在图像的一侧有链接,可以单击该链接滚动浏览所有不同的图像以查看它们 现在,我正在制作一个自动过程,它将运行一个函数,当用户单击其中一个链接时,该函数将更改图像。我需要确保在这个过程中,所有可能的不同图像的组合都被命中 假设有3顶不同的帽子,4件不同的衬衫,5条不同的裤子和6双不同的鞋子。我可以将其表示为一个数组,其中包含

我正在寻找一种最好的方法来循环一系列的选项,以确保我找到了所有可用的选项

我已经创建了一个特性,它允许客户端构建基本上是相互层叠的其他图像的图像。这些其他图像被分成不同的组。他们在图像的一侧有链接,可以单击该链接滚动浏览所有不同的图像以查看它们

现在,我正在制作一个自动过程,它将运行一个函数,当用户单击其中一个链接时,该函数将更改图像。我需要确保在这个过程中,所有可能的不同图像的组合都被命中

假设有3顶不同的帽子,4件不同的衬衫,5条不同的裤子和6双不同的鞋子。我可以将其表示为一个数组,其中包含每个组的选项数。当前数组是
[3,4,5,6]


在这个数组中循环以确保显示所有可能的选项的最佳方法是什么?

编辑:我使用jsperf对不同的方法进行了比较,Phrogz的方法显然是最快的,是第三种方法的两倍


如果我理解正确的话,你问的是关于计算每一列数字的不同基数。您可以递归地执行此操作

function options(opArr, fullArray){
    var i = 0, j = opArr.length;
    if(j < fullArray.length){ // if opArr doesn't have item from each group, add new group
        while(i < fullArray[j]){ // count up for this group
            newArr = opArr.slice(0); // clone opArr so we don't run into shared reference troubles, not sure if necessary
            newArr[j] = i;
            i++;
            options(newArr, fullArray); // recurse
        }
    }else{ // opArr is now a unique array of your items
        // console.log(opArr);
    }
}
options([], [3, 9, 3, 3]);

与前一种方法类似的另一种方法是,保留上次生成的数组,以减少循环中的计算量,但代价是在init中增加一个

function countUp2(arrayOfBases, callback, self){
    var arr = arrayOfBases.reverse(), x = 1, i = arr.length, last = [],
        me = (self===undefined?this:self),
        addOne = function(arr, n, fn, me){
        var j = n.length, i = j - 1;
        n[i]++;
        while(j = i, i-- > 0 && n[j] >= arr[j]){
            if(arr[j] === 0) n[i] += n[j], n[j] = 0;
            else n[i]++, n[j] -= arr[j];
        }
        return fn.call(me,n.slice(0)), n;
    };
    while (i-->0){
        if(arr[i] !== 0) x = x * arr[i];
        last[i] = 0;
    }
    i = 0;
    last[last.length-1] = -1;
    while(i < x){
        last = addOne(arr, last, callback, me);
        i++;
    }
}
countUp2([3,9,3,3], function(a){console.log(a);});
然后您可以根据自己的选择进行处理。

您需要所有阵列的

我在我的网站上有一个页面讨论这个问题,包括JavaScript实现:

例如,要以“向前”的顺序快速遍历它们,可以使用:

hats=['fez','fedora']
衬衫=['t-shirt','long']
裤子=[“短裤”,“牛仔裤”]
鞋子=['sneaker','loafer']
懒散产品(帽子、衬衫、裤子、鞋子),功能(帽子、衬衫、裤子、鞋子){
//您的函数将从数组中生成唯一的值组合
圆木(帽子、衬衫、裤子、鞋子);
});
函数lazyProduct(集合、f、上下文){
如果(!context)context=this;
var p=[],max=set.length-1,lens=[];
对于(var i=sets.length;i--;)透镜[i]=sets[i].length;
功能潜水(d){
var a=集合[d],len=镜头[d];

如果(d==max)for(var i=0;i可能这是一个迟来的答案。但我在中找到了一个不同的解决方案。所以任何人都可以尝试

const hats=['fez','fedora'];
const shirts=['t-shirt','long'];
康斯特裤子=[‘短裤’、‘牛仔裤’];
const shoes=[“运动鞋”,“懒汉”];
常量数据=[帽子、衬衫、裤子、鞋子];
常量键=[“帽子”、“衬衫”、“裤子”、“鞋子”];
功能组合(数据、键){
常量{length:numberOfArrays}=数据;
/**
*初始化名为index的变量
*具有数据数组的长度和
*用零填充。
*/
常量索引=数组(NumberOfArray).fill(0);
常量结果=[];
while(true){
设obj={};
/**
*从内部数组中获取值
*借助“索引”并制作对象
*/
for(设i=0;i=0&(索引[pick]+1>=data[pick].length)){
挑--;
}
/**
*找不到这样的数组,因此不再
*左组合
*/
如果(拾取<0)中断;
/**
*如果找到,则移动到该数组中的下一个元素
*/
索引[拾取]+;
/**
*对于此页右侧的所有阵列
*数组当前索引再次指向
*第一要素
*/
for(让i=pick+1;i

作为控制台包装{min height:100%!important;top:0}
显示代码总是有帮助的。你能发布你有哪些相关代码吗?不完全确定你在问什么-这是一个排列问题吗?即你想要[9,3,3,3],[3,9,3,3],[3,3,9,3],[3,3,9,3],[3,3,9]…类似的事情吗?@arxanas我会尽快得到代码,但我现在正在家里写这封信。谢谢你的关注。@Gabriel Florit如果我解释得不好,我很抱歉。这样想,我有一张展示一套服装的图片。有9顶不同的帽子,3件不同的衬衫,3条不同的裤子和3双不同的鞋。我需要循环浏览这些,以便显示所有不同的可能装备组合。这可能是我想要的。感谢@Phrogz。我计划为每个项目进行forEach,但它只是困扰我,必须有更好的方法来完成。你如何解决这个问题来应对lazyProduct功能n:第7:43行:应为赋值或函数调用,而不是看到表达式无未使用的表达式第8:43行:应为赋值或函数调用,而不是看到表达式无未使用的表达式?
function countUp2(arrayOfBases, callback, self){
    var arr = arrayOfBases.reverse(), x = 1, i = arr.length, last = [],
        me = (self===undefined?this:self),
        addOne = function(arr, n, fn, me){
        var j = n.length, i = j - 1;
        n[i]++;
        while(j = i, i-- > 0 && n[j] >= arr[j]){
            if(arr[j] === 0) n[i] += n[j], n[j] = 0;
            else n[i]++, n[j] -= arr[j];
        }
        return fn.call(me,n.slice(0)), n;
    };
    while (i-->0){
        if(arr[i] !== 0) x = x * arr[i];
        last[i] = 0;
    }
    i = 0;
    last[last.length-1] = -1;
    while(i < x){
        last = addOne(arr, last, callback, me);
        i++;
    }
}
countUp2([3,9,3,3], function(a){console.log(a);});
[0,0,0,0]
[0,0,0,1]
...
[0,8,1,2]
[0,8,2,0]
...
[2,8,2,1]
[2,8,2,2]
for (var h=0;h<hats.length;h++){
  var hat = hats[h];
  for (var s=0;s<shirts.length;s++){
    var shirt = shirts[s];
    for (var p=0;p<pants.length;p++){
      var pant = pants[p];
      for (var e=0;e<shoes.length;e++){
        var shoe = shoes[e];
        console.log(hat,shirt,pant,shoe);        
      }
    }
  }
}