从0循环到一个数字,并循环数组中的所有数字(javascript)

从0循环到一个数字,并循环数组中的所有数字(javascript),javascript,Javascript,以下是想法: var a = [4, 5, 6]; for (var m = 0; m < a[0]; m++) for (var n = 0; n < a[1]; n++) for (var p = 0; p < a[2]; p++) console.log(`${m} + ${n} + ${p} = ${m+n+p}`); 如果你把它拆开就容易多了。首先,需要为数组的每个元素创建一个序列 let series = num => Array.f

以下是想法:

var a = [4, 5, 6];
for (var m = 0; m < a[0]; m++)
  for (var n = 0; n < a[1]; n++)
    for (var p = 0; p < a[2]; p++)
      console.log(`${m} + ${n} + ${p} = ${m+n+p}`);

如果你把它拆开就容易多了。首先,需要为数组的每个元素创建一个序列

let series = num => Array.from({ length: num + 1 }, (n, i) => i); //creates an array with nums from  0 to num.
这是你问题的第一部分。然后你需要做一个系列的叉积

基本上,对于两个系列
[1,2,3]
[1,2,3,4]
,您将得到一组12个元素:

[2, 3, 4, 5, 3, 4, 5, 6, 4, 5, 6, 7]
为此,你可以:

let crossProduct = (a1, a2) => Array.prototype.concat.call(...a1.map(n1 => a2.map(n2 => n1 + n2)));
现在,您只需为每个系列设置一个
交叉积

let final = numbers.map(series).reduce(crossProduct);
就在这里:

let number=[4,5,6];
让series=num=>Array.from({length:num+1},(n,i)=>i);
让叉积=(a1,a2)=>Array.prototype.concat.call(…a1.map(n1=>a2.map(n2=>n1+n2));
让final=numbers.map(系列)、reduce(叉积);

控制台日志(最终)我们可以在不占用大量内存的情况下通过使用递归来实现这一点:

const process = (array, n, numbers) => {
    if (n < array.length) {
        // Not done yet, recurse once for each number at this level
        const max = array[n];
        for (let i = 0; i < max; ++i) {
            process(array, n + 1, [...numbers, i]);
        }
    } else {
        // Done with this level, process the numbers we got
        console.log(`${numbers.join(" + ")} = ${numbers.reduce((s, e) => s + e)}`);
    }
}

process([4, 5, 6], 0, []);

另一个不消耗大量内存且相当高效的解决方案是使用一个表示索引值的数组,并在每次迭代中更新它。 首先,创建一个数组,该数组表示每个元素中分别更新索引所需的迭代次数,例如,对于该数组
[1,2,3,4,5]
,您将得到:
[280、140、20、5、1]
这意味着索引[0]将每280次迭代更新一次,索引[1]将每140次迭代更新一次,依此类推。。 您将运行arr[n]*arr[n-1]*arr[n-2]*..*arr[0]迭代,就像您对普通嵌套for循环所做的那样

var arr = [1, 2, 7, 4, 5];

var indexes = Array.from({length: arr.length}, () => 0);
iterationsPerElement = arr.map((_, i) => arr.slice(i+1).reduce((acc, elem) => acc * elem, 1));

var totalIterations = iterationsPerElement[0] * arr[0];

for(var iteration = 1; iteration <= totalIterations; iteration++) {
    // sum those indexes
    console.log(`sum = ${indexes.reduce((acc, index) => acc + index, 0)}`);

    // update indexes
    for(i = 0; i < indexes.length; i++) {
        if(iteration % iterationsPerElement[i] == 0) {
            indexes[i]++;
            // empty the indexes on the right
            for(var j=i+1; j <indexes.length; j++) {
                indexes[j] = 0;
            }
        }
    }
}
var-arr=[1,2,7,4,5];
var index=Array.from({length:arr.length},()=>0);
iterationsPerElement=arr.map((μ,i)=>arr.slice(i+1).reduce((acc,elem)=>acc*elem,1));
var totalIterations=iterationsPerElement[0]*arr[0];
对于(var迭代=1;迭代acc+索引,0)}`);
//更新索引
对于(i=0;i对于(var j=i+1;j Hi,你想对数组中的所有值求和吗?如果是,你可以使用。你能解释一下你想做什么吗?@Nora-OP的代码不会对数组中的值求和。类似于@MichaelMontero的(好)问题:你确定输出是你想要的输出吗?你需要递归来保持代码的简短。
map()
没有帮助,
过滤器()
甚至更少。必须有一种方法避免将所有这些可预测的序列存储在内存中。@T.J.Crowder尽管它们在内存中停留时间不长,但由于我编写的
交叉积
的方式,您可能会遇到大集合的GC搅动问题,但是如果您想避免y的每个元素都有一个数组,您可以用一个简单的2 for循环重写它我们的集合。似乎它也有同样的问题。但是如果你有足够的内存去做…:-)哦,你是说我看过的那部连续剧generate@T.J.Crowder是的,2 for循环将保证在
crossProduct
上创建的对象更少。至于这个系列,可以使用生成器使它们变得懒惰,但我不知道性能是否会更好。这取决于javascript引擎。