是否有一个方法来检查两个数组是否包含相同的元素,以及是否在ruby中使用相同的索引获得相同的元素?

pdtvr36n  于 12个月前  发布在  Ruby
关注(0)|答案(5)|浏览(141)
arr = [1,4,6,3]
arr2 = [3,4,3,6]

arr.each do |item|
 p "X" if arr2.include?(item)
end

但上面的只返回X,如果元素被发现,但我希望它返回“O”时,两个数组包含相同的元素在同一索引,我不希望X重复,如果有一个以上的元素被发现。
我尝试使用eachwithindex,但无法获得结果

9lowa7mx

9lowa7mx1#

我会将逻辑 Package 到一个带有几个helper方法的类中:

class CodeBreaker
  def initialize(guess, code)
    @guess = guess
    @code = code
    @numbers = Set.new(code)

    return if guess.size == code.size

    raise ArgumentError, 'guess and code need to share the same size'
  end

  def hint 
    guess.map.with_index do |number, index|
      mark_when_equal_at_index(index) || mark_when_number_in_code(number) || '-'
    end
  end

  private

  attr_reader :guess, :code, :numbers

  def mark_when_equal_at_index(index)
    'O' if guess[index] == code[index]
  end

  def mark_when_number_in_code(number)
    'X' if code.include?(number)
  end
end

code_breaker = CodeBreaker.new([1, 4, 6, 3], [3, 4, 3, 6])
code_breaker.hint
#=> ["-", "O", "X", "X"]
cotxawn7

cotxawn72#

arr = [1, 4, 6, 3]
arr2 = [3, 4, 3, 6]

arr.each_with_index do |item, index|
  if item == arr2[index]
    puts "O"
  elsif arr2.include? item
    puts "X"
  else
    puts 'element not found'
  end
end

结果

element not found
O
X
X
b0zn9rqh

b0zn9rqh3#

我假设代码实现了一个棋盘游戏,在这种情况下效率并不重要。相反,重点应该放在可读性和易于测试上。
我假设两个数组大小相同,如示例中所示。

def equal_at_same_index?(arr1, arr2)
  arr1.zip(arr2).any? { |e1,e2| e1 == e2 }
end
def equal_at_different_indices?(arr1, arr2)
  arr1.any? { |e1| arr2.include?(e1) }
end
def equal_result(arr1, arr2)
  if equal_at_same_index?(arr1, arr2)
    'O'
  elsif equal_at_different_indices?(arr1, arr2)
    'X'
  else
    nil
  end
end

试试吧

equal_result([1,2,3,4], [5,6,3,7])
  #=> "O"
equal_result([1,2,3,4], [5,3,7,8])
  #=> "X"
equal_result([1,2,3,4], [5,6,7,8])
  #=> nil

如果不是nil,则可以显示equal_result的返回值。

k10s72fa

k10s72fa4#

我觉得这会让你如愿以偿。它使用Array#zip来检查两个数组,看看是否有相同的元素值出现在相同的索引中。

arr = [1, 4, 6, 3]
arr2 = [3, 4, 3, 6]

result = false
arr.zip(arr2) { |a, b| result = true if a == b }
puts result
rwqw0loc

rwqw0loc5#

我的第一个答案假设你只是想让相同的元素出现在相同的索引中。我添加了第二个答案,它提供了“X”和“O”。
除了第一个例子之外,我在所有例子中都加入了any?沿着zip(如卡里所示--这比在zip块中更改变量要好)。#intersect数组?就能拿到你想要的O型的案子
在下面的所有示例中,ref_ary与ary 1对应的是'O',ref_ary与ary 2对应的是'X',ref_ary与ary 3对应的是nil

ref_ary  = [1, 4, 6,  3]
ary1     = [3, 4, 3,  6]
ary2     = [3, 5, 3,  6]
ary3     = [7, 8, 9, 10]

# original answer but includes the 'O' part as well
def analyze(ref_ary, ary)
  result = nil
  ref_ary.zip(ary) { |a, b| result = 'O' if a == b }
  result || 'X' if ref_ary.intersect?(ary)
end

puts "ref vs ary1 = #{analyze(ref_ary, ary1)}"
puts "ref vs ary2 = #{analyze(ref_ary, ary2)}"
puts "ref vs ary3 = #{analyze(ref_ary, ary3)}"

# using `any?` you don't have to set result in the block.
def analyze2(ref_ary, ary)
  result = 'O' if ref_ary.zip(ary).any? { |a, b| a == b }
  result || 'X' if ref_ary.intersect?(ary)
end

puts "ref vs ary1 = #{analyze2(ref_ary, ary1)}"
puts "ref vs ary2 = #{analyze2(ref_ary, ary2)}"
puts "ref vs ary3 = #{analyze2(ref_ary, ary3)}"

# eliminates the intermediate variable `result`
def analyze3(ref_ary, ary)
  if ref_ary.zip(ary).any? { |a, b| a == b }
    'O'
  elsif ref_ary.intersect?(ary)
    'X'
  end
end

puts "ref vs ary1 = #{analyze3(ref_ary, ary1)}"
puts "ref vs ary2 = #{analyze3(ref_ary, ary2)}"
puts "ref vs ary3 = #{analyze3(ref_ary, ary3)}"
puts "ref vs ary3 = #{analyze3(ref_ary, ary3).class}"

相关问题