【问题标题】:How to generate ordered combinations of multiple sets of 2 elements如何生成多组 2 个元素的有序组合
【发布时间】:2021-08-22 20:33:30
【问题描述】:

我看到很多关于查找 所有 n 个集合的组合或排列的答案,但没有一个能够满足确保“顺序”问题的需要(如果这是正确的术语)。

在这种情况下,我们有 3 组 2 个元素:

let a1 = ['b', 'z']
let a2 = ['j', 'q']
let a3 = ['i', 'y']

输出所需的组合将是包含 3 个元素的所有组合,第一个元素来自 a1,第二个元素来自 a2,第三个元素来自 a3。最终输出如下所示:

['b', 'j', 'i']
['b', 'j', 'y']
['b', 'q', 'i']
['b', 'q', 'y']
['z', 'j', 'i']
['z', 'j', 'y']
['z', 'q', 'i']
['z', 'q', 'y']

请注意,上述内容包含所有排列或组合...而是强制执行规则,结果中的第一个元素来自第一个数组中的一个元素。结果中的第二个元素来自第二个数组中的元素之一。结果中的第三个元素来自第三个数组中的一个元素。

【问题讨论】:

  • 到目前为止您尝试了哪些方法以及您在哪些方面遇到了困难?

标签: javascript arrays loops


【解决方案1】:

您可以通过多种方式做到这一点。一种是使用递归:选择第一个数组的第一个元素,并将其作为其余数组的递归结果的前缀。然后对第一个数组的第二个值做同样的事情,......等等。

这是使用生成器实现的:

function * combis(arr, ...rest) {
    if (!arr) { // Base case: no more values to pick
        yield [];
        return;
    }
    for (let val of arr) {
        for (let result of combis(...rest)) {
            yield [val, ...result]; // Prefix value to recursive result
        }
    }
}

// Demo
let a1 = ['b', 'z'];
let a2 = ['j', 'q'];
let a3 = ['i', 'y'];

console.log(Array.from(combis(a1, a2, a3)));

【讨论】:

    【解决方案2】:

    这是一个使用rest parameters 来隔离每次调用的第一个数组的递归示例。

    const
      a1 = ['b', 'z'],
      a2 = ['j', 'q'],
      a3 = ['i', 'y'],
    
      combine = (arr, ...rest) => {
        return rest.length
          ? arr.flatMap(n => combine(...rest).map(m => [].concat(n, m)))
          : arr;
      },
    
      result = combine(a1, a2, a3);
    
    // logging
    result.forEach(r => console.log(`[${r.join(', ')}]`));
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-19
      • 1970-01-01
      • 2021-12-06
      • 1970-01-01
      • 1970-01-01
      • 2013-04-14
      • 1970-01-01
      • 2019-08-06
      相关资源
      最近更新 更多