用JavaScript解决这个看似简单的数组循环难题

用JavaScript解决这个看似简单的数组循环难题,javascript,arrays,list,loops,recursion,Javascript,Arrays,List,Loops,Recursion,出于某种原因,我很难接受这个。我喜欢拼图,但我在这方面做得不太好 下面的数组中可以包含大量集合,但深度永远不会超过本例中所示的深度(即,深度永远不会超过2维): 使用上面的内容作为输入,如何在JavaScript中生成以下数组 [['a', 'c', 'd'], ['a', 'c', 'e'], ['b', 'c', 'd'], ['b', 'c', 'e']] 我确信这个解决方案涉及递归,但它不是一个简单的树结构,所以它不像看上去那么简单。那么你在寻找笛卡尔积的置换 function pro

出于某种原因,我很难接受这个。我喜欢拼图,但我在这方面做得不太好

下面的数组中可以包含大量集合,但深度永远不会超过本例中所示的深度(即,深度永远不会超过2维):

使用上面的内容作为输入,如何在JavaScript中生成以下数组

[['a', 'c', 'd'], ['a', 'c', 'e'], ['b', 'c', 'd'], ['b', 'c', 'e']]
我确信这个解决方案涉及递归,但它不是一个简单的树结构,所以它不像看上去那么简单。

那么你在寻找笛卡尔积的置换

function product(list) {
    // Keep a current index for each set
    var indices = list.map(_ => 0); // More Firefox 22 promotion :)
    indices[indices.length - 1] = -1;
    var result = [];

    while(true) {
        // Get the next permutation
        for(var i = indices.length - 1; i >= 0; i--) {
            if(++indices[i] === list[i].length) {
                indices[i] = 0;
            } else {
                break;
            }
        }

        if(i === -1) {
            // All done!
            return result;
        }

        // Turn the array of indices into an array of values
        result.push(indices.map((n, i) => list[i][n]));
    }
}
所以你在寻找笛卡尔积的置换

function product(list) {
    // Keep a current index for each set
    var indices = list.map(_ => 0); // More Firefox 22 promotion :)
    indices[indices.length - 1] = -1;
    var result = [];

    while(true) {
        // Get the next permutation
        for(var i = indices.length - 1; i >= 0; i--) {
            if(++indices[i] === list[i].length) {
                indices[i] = 0;
            } else {
                break;
            }
        }

        if(i === -1) {
            // All done!
            return result;
        }

        // Turn the array of indices into an array of values
        result.push(indices.map((n, i) => list[i][n]));
    }
}

顺便说一句,我用它从嵌套结构生成CSS选择器,比如Sass。以下函数工作正常,非常简洁:

function cartesianProduct() {
    var result = this.selectors.reduce(function(a, b) {
        return a.map(function(x) {
            return b.map(function(y) {
                return [x, y].join(' ');
            });
        });
    })[0];
    return typeof result === 'string' ? result : result.join(', ');
}

顺便说一句,我用它从嵌套结构生成CSS选择器,比如Sass。以下函数工作正常,非常简洁:

function cartesianProduct() {
    var result = this.selectors.reduce(function(a, b) {
        return a.map(function(x) {
            return b.map(function(y) {
                return [x, y].join(' ');
            });
        });
    })[0];
    return typeof result === 'string' ? result : result.join(', ');
}


这是所有组合的列表。你需要递归。我尝试了递归,但没有成功,因为它没有简单的树结构。它比看起来更复杂。@sfjedi这确实是一个应该用递归解决的问题。你只需要找出归纳步骤:-)我称之为“笛卡尔积”,在js.s/infinite/arbitral large/中有很多解决这个问题的方法。(首先,Javascript不支持无限列表,我不确定即使在支持无限列表的语言中也能解决这个问题。至少没有什么意义,因为这与获得所有维度的第一个元素的列表是一样的。)这是所有组合的列表。你需要递归。我尝试了递归,但没有成功,因为它没有简单的树结构。它比看起来更复杂。@sfjedi这确实是一个应该用递归解决的问题。你只需要找出归纳步骤:-)我称之为“笛卡尔积”,在js.s/infinite/arbitral large/中有很多解决这个问题的方法。(首先,Javascript不支持无限列表,我不确定这是否可以用支持无限列表的语言解决。至少没有意义,因为这与获取所有维度的第一个元素的列表相同。)这样的玩笑(使用特定于FF的东西)…没关系。实际上,我使用的是node,所以我可以访问ES5阵列附加组件。让我试一试。这是一个非常聪明的方法,因为它避免了递归版本会经历的堆栈增长。@sfjedi:这是一个额外的ES6函数。(已经存在!)在节点上,使用
list.map(function(){return 0;})
index.map(function(n,i){return list[i][n];})
@sfjedi猜测:
函数({return 0;}
\uu
是从其他FP语言中盗用的约定,它的意思是“此参数意味着未使用”。我认为,如果您有一个未使用的参数未命名为
,Haskell或Ocaml实际上都会抛出一个错误。这样的玩笑(使用FF特定的东西)…没关系。实际上,我使用的是node,所以我可以访问ES5阵列附加组件。让我试一试。这是一个非常聪明的方法,因为它避免了递归版本会经历的堆栈增长。@sfjedi:这是一个额外的ES6函数。(已经存在!)在节点上,使用
list.map(function(){return 0;})
index.map(function(n,i){return list[i][n];})
@sfjedi猜测:
函数({return 0;}
\uu
是从其他FP语言中盗用的约定,它的意思是“此参数意味着未使用”。我认为Haskell或Ocaml如果有一个未使用的参数未命名为
“我确信解决方案涉及递归,但它不是一个简单的树结构,所以不像看上去那么简单。”嵌套CSS结构是一棵树:)我的意思是遍历树很容易,但我们在这里做的远不止这些。“我确信解决方案涉及递归,但它不是一个简单的树结构,所以它不像看上去那么简单。”嵌套CSS结构是一棵树:)我的意思是遍历一棵树很容易,但我们在这里做的远不止这些。