Compare two arrays except elements x, y, z (ruby)

is there any other way 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]) 

and the way out is

 ["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 
+4
source share
6 answers

There are probably many more concise ways to do this. Here is the first that came to my mind, and I am sure that it can be improved.

 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 

Essentially comparing the array manually. Check the same size, then check the elements one by one (but ignoring indexes, we are told to ignore). Break as soon as we find out that it’s pointless to continue.

+2
source

Simplest code (requires Ruby 1.8.7 or higher):

 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 

I suspect this will be faster (since it uses a single zip rather than individually requesting an array for each element) - although this is probably not the case where speed matters a lot.

On the sidelines, almost at any time, I directly index the array (for example, some_array[i] ) in Ruby, and not using a higher order method, such as map or each , I take this as a sign that I’m probably skipped something in the standard library, and the algorithm is likely to be less efficient than the optimized library.

+7
source

It looks better to me :):

 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 

The beauty of this is that it "chains" each_with_index with all? makes much cleaner code.
The bad news is that it only works with Ruby 1.8. 7 . In any case, I see no reason to use <1.8.7

+2
source

How about this?

 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 

Note This will work in Ruby 1.8.6. You can use the Dmitriy Nagirnyak method to optimize this further:

 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 
+2
source

Here's a solution for 1.9 that compares arrays for <and>, as well as ==:

 #!/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 
+1
source

Here's another short and very inefficient one:

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

Source: https://habr.com/ru/post/1302946/


All Articles