【问题标题】:Solve this seemingly simple array loop puzzle in JavaScript [duplicate]在 JavaScript 中解决这个看似简单的数组循环难题 [重复]
【发布时间】:2013-06-28 00:18:29
【问题描述】:

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

以下数组内部可以包含大量集合,但永远不会比您在此示例中看到的更深(即永远不会比二维更深):

var list = [['a', 'b'], ['c'], ['d', 'e']];

以上述为输入,如何在 JavaScript 中生成以下数组?

[['a', 'c', 'd'], ['a', 'c', 'e'], ['b', 'c', 'd'], ['b', 'c', 'e']]

我确定解决方案涉及递归,但它不是一个简单的树结构,所以它不像看起来那么简单。

【问题讨论】:

  • 这是所有组合的列表。你需要递归。
  • 是的。我尝试了递归,但它没有工作,因为它没有简单的树结构。它比看起来更复杂。
  • @sfjedi 这确实是一个应该用递归解决的问题。你只需要弄清楚归纳步骤:-)
  • 我称之为“笛卡尔积”,在 js 中有很多解决这个问题的方法。
  • s/无限量/任意大量/。 (一方面,Javascript 不支持无限列表,而且我不确定即使在支持的语言中这是否可以解决。至少没有意义,因为它与获取所有元素的第一个元素的列表相同尺寸。)

标签: javascript arrays list loops recursion


【解决方案1】:

所以您正在寻找 permutations 笛卡尔积?

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]));
    }
}

【讨论】:

  • 这样的戏弄(用那个 FF 特有的东西)..
  • 没关系。实际上,我使用的是节点,所以我可以访问 ES5 数组附加功能。让我试试这个。
  • 这是一个非常聪明的方法,因为它避免了递归版本会遇到的堆栈增长。
  • @sfjedi:这是一个额外的 ES6 函数。 (已经有了!)在 Node 上,使用 list.map(function() { return 0; })indices.map(function(n, i) { return list[i][n]; })
  • @sfjedi 猜测:function(_) { return 0; }_ 是从其他 FP 语言中窃取的约定,它的意思是“这个参数应该是未使用的”。我认为,如果您有一个未命名为 _ 的未使用参数,Haskell 或 Ocaml 实际上会引发错误。
【解决方案2】:

顺便说一句,我正在使用它从嵌套结构(如 Sass)生成 CSS 选择器。以下函数有效且非常简洁:

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 结构是一棵树:)
  • 我的意思是遍历一棵树很容易,但我们在这里做的远不止这些。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-04-03
  • 1970-01-01
  • 1970-01-01
  • 2020-11-16
  • 1970-01-01
  • 2017-02-28
  • 2020-04-16
相关资源
最近更新 更多