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)。在這一點上,這變得(相對)容易得出一個通用的解決方案... –