找不到完全符合您要求的软件包,但如果您想引入自己的方法,我想您可以这样做:
void main() {
print(combinations([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9, 10]
]));
// ([1, 4, 7], [1, 4, 8], [1, 4, 9], [1, 4, 10], ..., [3, 6, 9], [3, 6, 10])
}
Iterable<List<T>> combinations<T>(
List<List<T>> lists, [
int index = 0,
List<T>? prefix,
]) sync* {
prefix ??= <T>[];
if (lists.length == index) {
yield prefix.toList();
} else {
for (final value in lists[index]) {
yield* combinations(lists, index + 1, prefix..add(value));
prefix.removeLast();
}
}
}
更有效的解决方案但使用起来也有更大的风险,因为它确实需要combinations 的用户在使用输出时要小心,并确保不要保留内部Iterable 的任何实例:
void main() {
print(combinations([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9, 10]
]).map((e) => e.toList()));
// ([1, 4, 7], [1, 4, 8], [1, 4, 9], [1, 4, 10], ..., [3, 6, 9], [3, 6, 10])
}
Iterable<Iterable<T>> combinations<T>(
List<List<T>> lists, [
int index = 0,
List<T>? prefix,
]) sync* {
prefix ??= <T>[];
if (lists.length == index) {
yield prefix;
} else {
for (final value in lists[index]) {
yield* combinations(lists, index + 1, prefix..add(value));
prefix.removeLast();
}
}
}
此解决方案的问题是存在误用的风险,如下例所示:
final listOfCombinations = combinations([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9, 10]
]).toList();
print(listOfCombinations);
// [[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []]
应该是:
final listOfCombinations = combinations([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9, 10]
]).map((e) => e.toList()).toList();
print(listOfCombinations);
// [[1, 4, 7], [1, 4, 8], [1, 4, 9], [1, 4, 10], [1, 5, 7], [1, 5, 8], [1, 5, 9], [1, 5, 10], [1, 6, 7], [1, 6, 8], [1, 6, 9], [1, 6, 10], [2, 4, 7], [2, 4, 8], [2, 4, 9], [2, 4, 10], [2, 5, 7], [2, 5, 8], [2, 5, 9], [2, 5, 10], [2, 6, 7], [2, 6, 8], [2, 6, 9], [2, 6, 10], [3, 4, 7], [3, 4, 8], [3, 4, 9], [3, 4, 10], [3, 5, 7], [3, 5, 8], [3, 5, 9], [3, 5, 10], [3, 6, 7], [3, 6, 8], [3, 6, 9], [3, 6, 10]]
因此,如果您不想冒此类问题的风险,请使用第一个建议的解决方案。 :)