原始问题:最初的问题是如何迭代到嵌套循环ruby中的下一个元素。答案教会了解决我的问题的惯用方法,它需要一个不同的问题,以便当用户在谷歌搜索时,找到正确的东西
我有这个要求,其中有两个数组,每个数组都有排序的唯一值。
array1 = [2,3,4,5,6,7] #can not have repeated values[2,2,3]
array2 = [2,5,7]
我希望匹配两个数组的元素,并在找到匹配项时打印match found
,以及两个数组的索引。这是可以正常工作的代码。
array1.each do |arr1|
array2.each do |arr2|
if (arr1==arr2)
puts ("Match found element #{arr1} #{array1.index(arr1)} #{array2.index(arr2)}")
#some code here to move to the next element in array 1 and array 2 and continue looping from there
end
end
end
但这并没有使用数据结构的独特性和以任何方式排序。例如,在上面的示例中,2
中的元素array1
与2
中的元素array2
匹配,2
中的元素array2
不应该继续尝试匹配array1
的其他元素以及array1
应该移动到下一个元素。我知道有一种叫做next
的东西。但我认为只返回下一个元素并且不会将迭代器移动到下一个元素?此外,我必须移动到两个阵列的下一个。我该怎么做呢?
答案 0 :(得分:5)
如果要在两个数组之间找到匹配的元素,只需使用&
,如下所示:
array1 = [2,3,4,5,6,7] #does not have repeated values[2,2,3] and the values are sorted
array2 = [2,5,7]
matches = array1 & array2
=> [2, 5, 7]
要打印在每个数组中找到的匹配和索引,只需循环遍历matches数组:
matches.each do |number|
puts "Match found element #{number}"
puts "array1 index=#{array1.rindex(number)}"
puts "array2 index=#{array2.rindex(number)}"
end
Match found element 2
array1 index=0
array2 index=0
Match found element 5
array1 index=3
array2 index=1
Match found element 7
array1 index=5
array2 index=2
答案 1 :(得分:3)
对于您的代码,您只需使用break
退出array2循环,移动到array1中的下一个元素。
array2.each_with_index do |arr1, i1|
array1.each_with_index do |arr2, i2|
if (arr1==arr2)
puts ("Match found element array1: #{arr1} #{i1} and array2: #{arr2} #{i2}")
#if match element is found, exit from the current loop
break
end
end
end
Match found element array1: 2 0 and array2: 2 0
Match found element array1: 5 1 and array2: 5 3
Match found element array1: 7 2 and array2: 7 5
或
(array1 & array2).map{ |e| puts "Match found element #{e}" }
Match found element 2
Match found element 5
Match found element 7
答案 2 :(得分:2)
这是另一种方式:
array1 = [2,3,4,5,6,7]
array2 = [2,5,7]
h = array1.each_with_index.to_h
#=> {2=>0, 3=>1, 4=>2, 5=>3, 6=>4, 7=>5}
array2.each_with_index.with_object({}) { |(v,i),g| g[v] = [h[v],i] if h.key?(v) }
#=> {2=>[0, 0], 5=>[3, 1], 7=>[5, 2]}
第二个表达式可以分解如下:
e0 = array2.each_with_index
#=> #<Enumerator: [2, 5, 7]:each_with_index>
我们可以通过将它转换为数组来查看此枚举器的元素:
e0.to_a
#=> [[2, 0], [5, 1], [7, 2]]
e1 = e0.with_object({})
#=> #<Enumerator: #<Enumerator: [2, 5,7]:each_with_index>:with_object({})>
e1.to_a
#=> [[[2, 0], {}], [[5, 1], {}], [[7, 2], {}]]
枚举器e
的元素将传递给块,并由Enumerator#each分配给块变量。第一个(使用Enumerator#next获得)是:
(v,i),g = e1.next
#=> [[2, 0], {}]
v #=> 2
i #=> 0
g #=> {}
我们现在可以执行块:
g[v] = [h[v],i] if h.key?(v)
#=> g[2] = [h[2],0] if h.key(v)
# g[2] = [0,0] if true
e1
的下一个元素现在传递给块:
(v,i),g = e1.next
#=> [[5, 1], {}]
v #=> 5
i #=> 1
g #=> {2=>[0, 0]}
g[v] = [h[v],i] if h.key?(v)
# g[5] = [h[5], 1] if h.key?(5)
# g[5] = [3, 1] if true
g #=> {2=>[0, 0], 5=>[3, 1]}
e1
的最后一个元素的计算方法类似。