ES6使用生成器函数对列表进行分区

时间:2018-01-25 23:55:42

标签: javascript ecmascript-6

我试图将this answer中找到的函数从Python移植到ES6(减去排序,我不需要),但不能重现相同的输出。

它不是仅返回给定长度的分区,而是在Python版本中,它当前返回所有分区,包括该长度。

在下面的示例中,所需的输出是长度为3的数组,仅返回

我是否误解了生成器功能的某些方面?



while (in.read(buf) >= 0 || buf.position != 0) {
   buf.flip();
   out.write(buf);
   buf.compact();    // In case of partial write
}




同样为a bin

1 个答案:

答案 0 :(得分:1)

不,从Python到ES6的转换只有一个错误。

在你if (n - 1 > k - groups.length)的行上,1应该是i而不是(只是转录错误)。

所以该行的正确版本是:

if (n - i > k - groups.length)

一旦改变它就会给出预期的输出:

[["A", "B"], ["C"], ["D"]]
[["A", "C"], ["B"], ["D"]]
[["A"], ["B", "C"], ["D"]]
[["A", "D"], ["B"], ["C"]]
[["A"], ["B", "D"], ["C"]]
[["A"], ["B"], ["C", "D"]]

现在我有兴趣深入了解它是如何运作的;)

以下是完成该更改的完整代码:

const kPartitions = (seq, k) => {
  const n = seq.length
  var groups = []
  function* generatePartitions(i) {
    if (i >= n) {
      yield groups.map(group => [...group])
    }
    else {
      if (n - i > k - groups.length) {
        for (let group of groups) {
          group.push(seq[i])
          yield* generatePartitions(i + 1)
          group.pop()
        }
      }
      if (groups.length < k) {
        groups.push([seq[i]])
        yield* generatePartitions(i + 1)
        groups.pop()
      }
    }
  }
  return generatePartitions(0)
}

for (var partitions of kPartitions(['A', 'B', 'C', 'D'], 3)) {
  console.log(partitions)
}