a.combination(3).to_a
给出了所有可能的组合,但是以随机顺序。
让我们来看看:
a.combination(3).to_a
#=> [
# ["melon | apple", "kiwi | melon", "apple | orange"],
# ["melon | apple", "kiwi | melon", "pineapple | kiwi"],
# ["melon | apple", "apple | orange", "pineapple | kiwi"],
# ["kiwi | melon", "apple | orange", "pineapple | kiwi"]
# ]
显然,这既不包含["kiwi | melon", "melon | apple", "apple | orange"]
也不["pineapple | kiwi", "kiwi | melon", "melon | apple"]
。
让那些为好,你必须使用permutation
代替:
a.permutation(3).to_a
#=> [
# ["melon | apple", "kiwi | melon", "apple | orange"],
# ["melon | apple", "kiwi | melon", "pineapple | kiwi"],
# ["melon | apple", "apple | orange", "kiwi | melon"],
# ["melon | apple", "apple | orange", "pineapple | kiwi"],
# ["melon | apple", "pineapple | kiwi", "kiwi | melon"],
# ["melon | apple", "pineapple | kiwi", "apple | orange"],
# ["kiwi | melon", "melon | apple", "apple | orange"], <--- here
# ["kiwi | melon", "melon | apple", "pineapple | kiwi"],
# ["kiwi | melon", "apple | orange", "melon | apple"],
# ["kiwi | melon", "apple | orange", "pineapple | kiwi"],
# ["kiwi | melon", "pineapple | kiwi", "melon | apple"],
# ["kiwi | melon", "pineapple | kiwi", "apple | orange"],
# ["apple | orange", "melon | apple", "kiwi | melon"],
# ["apple | orange", "melon | apple", "pineapple | kiwi"],
# ["apple | orange", "kiwi | melon", "melon | apple"],
# ["apple | orange", "kiwi | melon", "pineapple | kiwi"],
# ["apple | orange", "pineapple | kiwi", "melon | apple"],
# ["apple | orange", "pineapple | kiwi", "kiwi | melon"],
# ["pineapple | kiwi", "melon | apple", "kiwi | melon"],
# ["pineapple | kiwi", "melon | apple", "apple | orange"],
# ["pineapple | kiwi", "kiwi | melon", "melon | apple"], <--- here
# ["pineapple | kiwi", "kiwi | melon", "apple | orange"],
# ["pineapple | kiwi", "apple | orange", "melon | apple"],
# ["pineapple | kiwi", "apple | orange", "kiwi | melon"]
# ]
你可能已经知道select
可以用来筛选出正确的元素,但如何的条件是什么样子?
让我们来匹配对:
a = 'kiwi | melon'
b = 'melon | apple'
我们可以split
那些' | '
得到部分:
a.split(' | ') #=> ["kiwi", "melon"]
b.split(' | ') #=> ["melon", "apple"]
这是一个比赛,如果a
第一个字的最后一个字b
匹配“ :
a.split(' | ').last == b.split(' | ').first
#=> true
要检查这对于在阵列中的每个连续对字符串的,我们可以使用each_cons
:
['kiwi | melon', 'melon | apple', 'apple | orange'].each_cons(2) do |a, b|
p a.split(' | ').last == b.split(' | ').first
end
它首先经过'kiwi | melon'
和'melon | apple'
到块,然后'melon | apple'
和'apple | orange'
。
对于这个数组,输出是:
true
true
要确定块11返回true
将所有对,我们可以追加all?
到each_cons
:
['kiwi | melon', 'melon | apple', 'apple | orange'].each_cons(2).all? do |a, b|
a.split(' | ').last == b.split(' | ').first
end
而这正是什么我们可以通过select
:
a.permutation(3).select do |sub_array|
sub_array.each_cons(2).all? do |a, b|
a.split(' | ').last == b.split(' | ').first
end
end
#=> [
# ["kiwi | melon", "melon | apple", "apple | orange"],
# ["pineapple | kiwi", "kiwi | melon", "melon | apple"]
# ]
请注意,这仍会创建一个包含所有排列的巨大临时数组,并且会为每个比较分割字符串,因此您可能需要寻找更优化的解决方案。但是这应该让你开始。
是否有一个很好的理由奇怪的数据结构?看起来你最好使用'Hash'而不是用'|'分开的字符串数组...... –
很可能,这是我从数据供应商处获得的数据 –
其实,你可能是最好的将其转换为[树数据结构](https://github.com/evolve75/RubyTree)。在这一点上,这变得(相对)容易得出一个通用的解决方案... –