如何匹配两个数组的内容并得到相应的索引ruby

时间:2015-05-22 05:13:39

标签: arrays ruby

原始问题:最初的问题是如何迭代到嵌套循环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中的元素array12中的元素array2匹配,2中的元素array2不应该继续尝试匹配array1的其他元素以及array1应该移动到下一个元素。我知道有一种叫做next的东西。但我认为只返回下一个元素并且不会将迭代器移动到下一个元素?此外,我必须移动到两个阵列的下一个。我该怎么做呢?

3 个答案:

答案 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的最后一个元素的计算方法类似。