2017-07-04 72 views
-1
特定標準匹配的數組中的

我有以下的數組:找到所有的組合中的Ruby

a = ["melon | apple", "kiwi | melon", "apple | orange", "pineapple | kiwi"] 

我想的,得到所有字符串由字符串元素和前部的連接後半部分("|"後) (在"|"之前)以下字符串元素。 a.combination_with_criteria(3).to_a應該輸出:

["kiwi | melon", "melon | apple", "apple | orange"] 
["pineapple | kiwi", "kiwi | melon", "melon | apple"] 

a.combination(3).to_a給出了所有可能的組合,但以隨機順序。

也許爲了這個目的使用散列更好。

+0

是否有一個很好的理由奇怪的數據結構?看起來你最好使用'Hash'而不是用'|'分開的字符串數組...... –

+0

很可能,這是我從數據供應商處獲得的數據 –

+0

其實,你可能是最好的將其轉換爲[樹數據結構](https://github.com/evolve75/RubyTree)。在這一點上,這變得(相對)容易得出一個通用的解決方案... –

回答

0

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"] 
# ] 

請注意,這仍會創建一個包含所有排列的巨大臨時數組,並且會爲每個比較分割字符串,因此您可能需要尋找更優化的解決方案。但是這應該讓你開始。

1

這似乎工作:

def find_chains(input) 
    # Split input into usable value pairs. 
    pairs = input.map { |s| s.split(" | ") } 

    pairs.permutation(3).select do |ar| 
    ar[0][1] == ar[1][0] && ar[1][1] == ar[2][0] 
    end 
end 

input = ["melon | apple", "kiwi | melon", "apple | orange", "pineapple | kiwi"] 

find_chains(input).each do |match| 
    puts "match: " + match.map { |ar| ar.join(" | ")}.join(", ") 
end 

# Output: 
# 
# match: kiwi | melon, melon | apple, apple | orange 
# match: pineapple | kiwi, kiwi | melon, melon | apple