比较除了元素x,y,z(ruby)之外的两个数组

时间:2010-03-03 03:14:05

标签: ruby arrays comparison

还有其他simple,nicer方法吗?

require 'pp'

a1 = ["02/28/10","Webinars","131","0","26 Feb 2010","0","3d, 8h, 49m, 18s"]
a2 = ["02/20/10","Webinars","131","9","26 Feb 2010","0","3d, 8h, 49m, 18s"]

def compare(array1,array2,ignore)

  tmp1 = Array.new
  tmp2 = Array.new
  0.upto(array1.length-1) {|index|
    if !ignore.include?(index)
      tmp1 << array1[index]
      tmp2 << array2[index]
    end
  }
  if tmp1 == tmp2 
    return true
  else
    return false    
  end
end

pp a1
pp a2
puts
puts compare(a1,a2,[0,3])

,输出

["02/28/10", "Webinars", "131", "0", "26 Feb 2010", "0", "3d, 8h, 49m, 18s"]
["02/20/10", "Webinars", "131", "9", "26 Feb 2010", "0", "3d, 8h, 49m, 18s"]

true

6 个答案:

答案 0 :(得分:7)

最简单的代码(需要Ruby 1.8.7或更高版本):

def compare(array_a, array_b, ignore_list)
  array_a.zip(array_b).each_with_index.all? do |a, b, idx|
    a == b or ignore_list.include? idx
  end
end

我怀疑它也会更快(因为它使用单个zip而不是单独询问每个项目的数组) - 尽管这可能不是速度很重要的情况。

顺便说一下,几乎任何时候我都在直接索引Ruby中的数组(如some_array[i])而不是使用更高阶的方法,例如mapeach,我把它作为一个标志,我可能在标准库中遗漏了一些东西,算法的效率可能低于高度优化的库函数。

答案 1 :(得分:2)

对我来说这看起来更好:):

def compare(array1, array2 = [], ignore = [])
  return false if array1.length != array2.length
  array1.each_with_index.all? do |e1, i1|
    array2[i1] == e1 || ignore.include?(i1)
  end
end

这样做的好处在于它将each_with_index“链接”all?,使代码更加清晰。
不好的是它只适用于Ruby 1.8。 7 。无论如何,没有理由使用&lt; 1.8.7

答案 2 :(得分:2)

可能有很多简洁的方法可以做到这一点。这是我想到的第一个,我相信可以改进。

def compare(array1, array2, ignore)
  return false if array1.size != array2.size
  0.upto(array1.size) do |i|
    return false if !ignore.include?(i) && array1[i] != array2[i]
  end
  return true
end

基本上,手动数组比较。检查相同的大小,然后逐个检查元素(但忽略我们被告知忽略的索引)。一旦我们知道继续下去就没有意义。

答案 3 :(得分:2)

这个怎么样?

require 'enumerator'
def compare (a1, a2, i)
  a1.size == a2.size and
    ( a1.enum_for(:each_with_index).select{ |v, j| !i.include?(j)} ==
      a2.enum_for(:each_with_index).select{ |v, j| !i.include?(j)} )

end

compare([1,2,3,4,5], [1,7,6,4,5], [1,2]) #true
compare([1,2,3,4,5], [1,7,6,4,5], [1,2]) #true

注意 这将适用于Ruby 1.8.6。您可以使用Dmitriy Nagirnyak的方法进一步优化:

def compare (a1, a2, i)
  a1.size == a2.size and
    a1.enum_for(:each_with_index).all?{|v, j| a2[j] == v or i.include?(j)}
end

答案 4 :(得分:1)

这是1.9的解决方案,用于比较&lt;和&gt;以及==:

#!/usr/bin/ruby1.9

# Return -1 if array1 < array2
#         0 if array1 == array2
#        +1 if array1 > array2
# ignore contains indices of elements to ignore

def compare(array1, array2, ignore)
  filter = lambda do |a|
    a.collect.with_index do |e, i|
      if ignore.include?(i)
        ''
      else
        e
      end
    end
  end
  filter[array1] <=> filter[array2]
end

array1 = ["02/28/10","Webinars","131","0","26 Feb 2010","0","3d, 8h, 49m, 18s"]
array2 = ["02/20/10","Webinars","131","9","26 Feb 2010","0","3d, 8h, 49m, 18s"]

p compare(array1, array2, [0, 3])    # => 0
p compare(array1, array2, [0])       # => -1
p compare(array1, array2, [3])       # => 1

答案 5 :(得分:0)

这是另一个,简洁而且效率极低:

def compare a1, a2, i
  [a1,a2].map { |a|
    a.values_at(*((0...a.length).to_a - i))
  }.inject(&:==)
end