Gabriele Marrone
11/23/2006 3:57:00 AM
On 23/nov/06, at 03:14, Gabriele Marrone wrote:
> def are_these_arrays_equal?(a1, a2)
> return false if a1.size != a2.size
> a2 = a2.dup # a2 will be modified, so let's duplicate it
> for i1 in a1
> return false unless a2.include? i1
> # need to delete just the *first* occurrence of i1 in a2
> # (Array#delete deletes them all)
> found = false
> a2.delete_if {|i2| found = !found && i1 == i2 }
> end
> # a2 is now empty, since its size was equal to a1 size
> return true
> end
>
> This should work with multiple occurrences of the same object,
> different objects (so different object_id) that seem to be equal
> (by comparing them with ==), nil values (#find() is a bit tricky),
> objects that do not respond to <=>.
> Did I miss any case?
I'm replying to myself.
Morton smartly pointed out that elements can be arrays themselves.
So, should we treat them as any other kind of object and compare them
with ==?
I guess we should want to recursively apply our equality concept
given by the OP.
So I modified my version:
def are_these_arrays_equal?(a1, a2)
return false unless a1.kind_of? Array and a2.kind_of? Array
return false if a1.size != a2.size
a2 = a2.dup # a2 will be modified, so let's duplicate it
for i1 in a1
return false unless a2.any? do |i2|
if i1.kind_of? Array
are_these_arrays_equal?(i1, i2)
else
i1 == i2
end
end
# need to delete just the *first* occurrence of i1 in a2
# (Array#delete deletes them all)
found = false
a2.delete_if do |i2|
break if found # breaks if already deleted
found = !found && if i1.kind_of? Array
are_these_arrays_equal?(i1, i2)
else
i1 == i2
end
end
end
# a2 is now empty, since its size was equal to a1 size
return true
end
Of course this would be much simpler if we were redefining Array#==
with this algorythm (there would be no need to check #kind_of?) but I
really DON'T want to know what could happen by redefining Array#==,
since every library could rely on it :P
(Actually, it might be funny to find out)
--
Gabriele Marrone