我有以下数组:
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 :(得分: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
答案 1 :(得分: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
要确定该块是否为所有对返回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"]
# ]
请注意,这仍会创建一个包含所有排列的巨大临时数组,并为每次比较拆分字符串,因此您可能希望寻找更优化的解决方案。但这应该让你开始。