groovy 配对列表中每个元素的方法
groovy way to pair each element in a list
每个元素都应该相互配对,但只能配对一次。
给定一个列表 A, B, C
我想制作以下配对列表:(A,B), (A,C), (B,C)
类似地,对于 4 个元素 A, B, C, D
,结果应为 (A,B), (A,C), (A,D), (B,C), (B,D), (C,D)
。
我尝试了 eachPermutation、eachCombintation,但找不到好的方法。如果你能告诉我这个操作的数学名称是什么,那将是一个很大的帮助。
递归执行如何?第一个元素和尾部的组合,然后递归列表的其余部分。
def comb(l,r=[]) {
if (l) {
r.addAll( [l.head(), l.tail()].combinations() )
return comb(l.tail(), r)
}
return r
}
def m = ['a','b','c','d']
def result = comb(m)
assert result == [['a', 'b'], ['a', 'c'], ['a', 'd'], ['b', 'c'], ['b', 'd'], ['c', 'd']]
您可以使用 combinations
、toSet
、sort
和 findAll
,其余的大小等于 2:
def uniqueCombinations = { l ->
[l,l].combinations()*.toSet()*.sort().unique().findAll { it.size() == 2 }
}
l=[1,2,3]
assert uniqueCombinations(l) == [[1, 2], [1, 3], [2, 3]]
Groovy 中可能没有这样的功能,但您可以很容易地实现它:
def pairs(def elements) {
return elements.tail().collect { [elements.head(), it] } + (elements.size() > 1 ? pairs(elements.tail()) : [])
}
assert pairs(['A', 'B', 'C']) == [['A', 'B'], ['A', 'C'], ['B', 'C']]
assert pairs(['A', 'B', 'C', 'D']) == [['A', 'B'], ['A', 'C'], ['A', 'D'], ['B', 'C'], ['B', 'D'], ['C', 'D']]
对于 eachCombination
它将是:
def l = ['A', 'B', 'C', 'D'], result = []
[l, l].eachCombination {
if ( ! ( it in result*.intersect( it ) || it[0] == it[1] ) ) {
result << it.reverse()
}
}
assert result == [
['A', 'B'], ['A', 'C'], ['A', 'D'], ['B', 'C'], ['B', 'D'], ['C', 'D']
]
有点晚,但似乎 subsequences 会很快解决这个问题。它提供的不仅仅是对,但限制结果集对未来的读者来说是微不足道且显而易见的:
def pairs(def l) {
l.subsequences().findAll {it.size() == 2}
}
assert pairs(['a','b','c']) == [['a','b'], ['a','c'], ['b', 'c']] as Set
assert pairs(['a', 'b', 'c', 'd']) == [['a', 'b'], ['a', 'c'], ['a', 'd'], ['b', 'c'], ['b', 'd'], ['c', 'd']] as Set
每个元素都应该相互配对,但只能配对一次。
给定一个列表 A, B, C
我想制作以下配对列表:(A,B), (A,C), (B,C)
类似地,对于 4 个元素 A, B, C, D
,结果应为 (A,B), (A,C), (A,D), (B,C), (B,D), (C,D)
。
我尝试了 eachPermutation、eachCombintation,但找不到好的方法。如果你能告诉我这个操作的数学名称是什么,那将是一个很大的帮助。
递归执行如何?第一个元素和尾部的组合,然后递归列表的其余部分。
def comb(l,r=[]) {
if (l) {
r.addAll( [l.head(), l.tail()].combinations() )
return comb(l.tail(), r)
}
return r
}
def m = ['a','b','c','d']
def result = comb(m)
assert result == [['a', 'b'], ['a', 'c'], ['a', 'd'], ['b', 'c'], ['b', 'd'], ['c', 'd']]
您可以使用 combinations
、toSet
、sort
和 findAll
,其余的大小等于 2:
def uniqueCombinations = { l ->
[l,l].combinations()*.toSet()*.sort().unique().findAll { it.size() == 2 }
}
l=[1,2,3]
assert uniqueCombinations(l) == [[1, 2], [1, 3], [2, 3]]
Groovy 中可能没有这样的功能,但您可以很容易地实现它:
def pairs(def elements) {
return elements.tail().collect { [elements.head(), it] } + (elements.size() > 1 ? pairs(elements.tail()) : [])
}
assert pairs(['A', 'B', 'C']) == [['A', 'B'], ['A', 'C'], ['B', 'C']]
assert pairs(['A', 'B', 'C', 'D']) == [['A', 'B'], ['A', 'C'], ['A', 'D'], ['B', 'C'], ['B', 'D'], ['C', 'D']]
对于 eachCombination
它将是:
def l = ['A', 'B', 'C', 'D'], result = []
[l, l].eachCombination {
if ( ! ( it in result*.intersect( it ) || it[0] == it[1] ) ) {
result << it.reverse()
}
}
assert result == [
['A', 'B'], ['A', 'C'], ['A', 'D'], ['B', 'C'], ['B', 'D'], ['C', 'D']
]
有点晚,但似乎 subsequences 会很快解决这个问题。它提供的不仅仅是对,但限制结果集对未来的读者来说是微不足道且显而易见的:
def pairs(def l) {
l.subsequences().findAll {it.size() == 2}
}
assert pairs(['a','b','c']) == [['a','b'], ['a','c'], ['b', 'c']] as Set
assert pairs(['a', 'b', 'c', 'd']) == [['a', 'b'], ['a', 'c'], ['a', 'd'], ['b', 'c'], ['b', 'd'], ['c', 'd']] as Set