Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > Hash, ==, key-value comparison

Reply
Thread Tools

Hash, ==, key-value comparison

 
 
walter@mwsewall.com
Guest
Posts: n/a
 
      04-15-2004
Ok,

ALthough the docs don't mention it, Hash comparison using == checks
not only the key value pairs, but also the default value / default
procs.

So how does one compare 2 hashes key-value pairs. I can see that it
might be useful to distinguish between 2 hashes whose key-value pairs
are the same but the default value/default proc are different, but I
would think that would be much less often than wanting to know if the
key-value pairs are the same.

Maybe I am thinking about this all wrong, but I always viewed a Hash
as a Hash, and yes some might have a default value and some might
have a default proc, but it is the data (the key-value pairs) that,
to me, make up the Hash. The default data/procs are convenience that
make it easier to work with a Hash, but I would think that {} and
Hash.new(3) would be == if their key-value pairs would be equal.

Assuming that I am in the minority here about ==, what is the proper
way to see if 2 Hashes key-value pairs are the same.



Walt
************************************************** ***
Walter Szewelanczyk
IS Director
M.W. Sewall & CO. email :
259 Front St. Phone : (207) 442-7994 x 128
Bath, ME 04530 Fax : (207) 443-6284
************************************************** ***



 
Reply With Quote
 
 
 
 
Elias Athanasopoulos
Guest
Posts: n/a
 
      04-15-2004
On Fri, Apr 16, 2004 at 02:04:10AM +0900, wrote:
> Ok,
>
> ALthough the docs don't mention it, Hash comparison using == checks
> not only the key value pairs, but also the default value / default
> procs.
>
> So how does one compare 2 hashes key-value pairs. I can see that it


I can contribute a patch to:

* Change '==' method to compare only key-value pairs.
* Add Hash#=== method to act like current Hash#==

Comments?

Regards,
--
University of Athens I bet the human brain
Physics Department is a kludge --Marvin Minsky




 
Reply With Quote
 
 
 
 
walter@mwsewall.com
Guest
Posts: n/a
 
      04-15-2004

> On Fri, Apr 16, 2004 at 02:04:10AM +0900, wrote: >
> Ok, > > ALthough the docs don't mention it, Hash comparison using ==
> checks > not only the key value pairs, but also the default value /
> default > procs. > > So how does one compare 2 hashes key-value pairs.
> I can see that it
>
> I can contribute a patch to:
>
> * Change '==' method to compare only key-value pairs.
> * Add Hash#=== method to act like current Hash#==
>
> Comments?
>


Personally, I like the idea. You get my vote!

> Regards,
> --
> University of Athens I bet the human brain
> Physics Department is a kludge --Marvin Minsky
>
>
>



Thanks,


Walt
************************************************** ***
Walter Szewelanczyk
IS Director
M.W. Sewall & CO. email :
259 Front St. Phone : (207) 442-7994 x 128
Bath, ME 04530 Fax : (207) 443-6284
************************************************** ***



 
Reply With Quote
 
Elias Athanasopoulos
Guest
Posts: n/a
 
      04-15-2004
On Fri, Apr 16, 2004 at 02:30:02AM +0900, wrote:
>
> > On Fri, Apr 16, 2004 at 02:04:10AM +0900, wrote: >
> > Ok, > > ALthough the docs don't mention it, Hash comparison using ==
> > checks > not only the key value pairs, but also the default value /
> > default > procs. > > So how does one compare 2 hashes key-value pairs.
> > I can see that it
> >
> > I can contribute a patch to:
> >
> > * Change '==' method to compare only key-value pairs.
> > * Add Hash#=== method to act like current Hash#==
> >
> > Comments?
> >

>
> Personally, I like the idea. You get my vote!


I will add a ChangeLog entry if it is accepted.

elathan@velka:~/hacking/ruby> cat ../test.rb
h1 = { "a" => 1, "b" => 2}

h2 = Hash.new(2)
h2["a"] = 1
h2["b"] = 2

puts h1 == h2
puts h1 === h2
elathan@velka:~/hacking/ruby> ./ruby ../test.rb
true
false

Enjoy,
--
University of Athens I bet the human brain
Physics Department is a kludge --Marvin Minsky


--- /home/elathan/hacking/ruby/hash.c.orig 2004-04-15 04:46:29.000000000 +0300
+++ /home/elathan/hacking/ruby/hash.c 2004-04-15 04:52:39.000000000 +0300
@@ -1425,6 +1425,48 @@
}
if (RHASH(hash1)->tbl->num_entries != RHASH(hash2)->tbl->num_entries)
return Qfalse;
+
+ data.tbl = RHASH(hash2)->tbl;
+ data.result = Qtrue;
+ st_foreach(RHASH(hash1)->tbl, equal_i, (st_data_t)&data);
+
+ return data.result;
+}
+
+/*
+ * call-seq:
+ * hsh === other_hash => true or false
+ *
+ * Equality---Two hashes are strictly equal if they each contain the same number
+ * of keys and if each key-value pair is equal to (according to
+ * <code>Object#==</code>) the corresponding elements in the other
+ * hash. Both hashes must have also equal default values/procs.
+ *
+ * h1 = { "a" => 1, "c" => 2 }
+ * h2 = { 7 => 35, "c" => 2, "a" => 1 }
+ * h3 = { "a" => 1, "c" => 2, 7 => 35 }
+ * h4 = { "a" => 1, "d" => 2, "f" => 35 }
+ * h1 === h2 #=> false
+ * h2 === h3 #=> true
+ * h3 === h4 #=> false
+ *
+ */
+
+static VALUE
+rb_hash_strict_equal(hash1, hash2)
+ VALUE hash1, hash2;
+{
+ struct equal_data data;
+
+ if (hash1 == hash2) return Qtrue;
+ if (TYPE(hash2) != T_HASH) {
+ if (!rb_respond_to(hash2, rb_intern("to_hash"))) {
+ return Qfalse;
+ }
+ return rb_equal(hash2, hash1);
+ }
+ if (RHASH(hash1)->tbl->num_entries != RHASH(hash2)->tbl->num_entries)
+ return Qfalse;
if (!(rb_equal(RHASH(hash1)->ifnone, RHASH(hash2)->ifnone) &&
FL_TEST(hash1, HASH_PROC_DEFAULT) == FL_TEST(hash2, HASH_PROC_DEFAULT)))
return Qfalse;
@@ -1435,7 +1477,6 @@

return data.result;
}
-
static int
rb_hash_invert_i(key, value, hash)
VALUE key, value;
@@ -2365,6 +2406,7 @@
rb_define_method(rb_cHash,"inspect", rb_hash_inspect, 0);

rb_define_method(rb_cHash,"==", rb_hash_equal, 1);
+ rb_define_method(rb_cHash,"===", rb_hash_strict_equal, 1);
rb_define_method(rb_cHash,"[]", rb_hash_aref, 1);
rb_define_method(rb_cHash,"fetch", rb_hash_fetch, -1);
rb_define_method(rb_cHash,"[]=", rb_hash_aset, 2);


 
Reply With Quote
 
Ara.T.Howard
Guest
Posts: n/a
 
      04-15-2004
On Fri, 16 Apr 2004 wrote:

> Ok,
>
> ALthough the docs don't mention it, Hash comparison using == checks
> not only the key value pairs, but also the default value / default
> procs.
>
> So how does one compare 2 hashes key-value pairs. I can see that it
> might be useful to distinguish between 2 hashes whose key-value pairs
> are the same but the default value/default proc are different, but I
> would think that would be much less often than wanting to know if the
> key-value pairs are the same.
>
> Maybe I am thinking about this all wrong, but I always viewed a Hash
> as a Hash, and yes some might have a default value and some might
> have a default proc, but it is the data (the key-value pairs) that,
> to me, make up the Hash. The default data/procs are convenience that
> make it easier to work with a Hash, but I would think that {} and
> Hash.new(3) would be == if their key-value pairs would be equal.
>
> Assuming that I am in the minority here about ==, what is the proper
> way to see if 2 Hashes key-value pairs are the same.


how about

(a.keys - b.keys).empty? and (a.values - b.values).empty?

-a
--
================================================== =============================
| EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
| PHONE :: 303.497.6469
| ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328
| URL :: http://www.ngdc.noaa.gov/stp/
| TRY :: for l in ruby perl;do $l -e "print \"\x3a\x2d\x29\x0a\"";done
================================================== =============================

 
Reply With Quote
 
walter@mwsewall.com
Guest
Posts: n/a
 
      04-15-2004

<snip>
> >
> > Assuming that I am in the minority here about ==, what is the proper
> > way to see if 2 Hashes key-value pairs are the same.

>
> how about
>
> (a.keys - b.keys).empty? and (a.values - b.values).empty?
>


Thanks, but that doesn't work

a = {'A'=>1, 'B'=>2, 'C'=>3}
b = {'A'=>3, 'B'=>2, 'C'=>1}
puts (a.keys - b.keys).empty? and (a.values - b.values).empty?

here the keys and values are the same but belong to different
elements.


I know ways to do it, but it seems ugly and overcomplicated. Also
since it is pure ruby it is much
c = Hash.new{|h,k| h[k]=0}
c['A'] = 1
c['B'] = 2
c['C'] = 3

puts (a.size == b.size) && !(a.keys.collect{|k| a[k] ==
b[k]}.include?(false))
puts (a.size == c.size) && !(a.keys.collect{|k| a[k] ==
c[k]}.include?(false))


I am sure I can get a much faster ruby version, but not as nice as a
== b.



Walt
************************************************** ***
Walter Szewelanczyk
IS Director
M.W. Sewall & CO. email :
259 Front St. Phone : (207) 442-7994 x 128
Bath, ME 04530 Fax : (207) 443-6284
************************************************** ***



 
Reply With Quote
 
Mark Hubbart
Guest
Posts: n/a
 
      04-15-2004

On Apr 15, 2004, at 10:04 AM, wrote:

> Ok,
>
> ALthough the docs don't mention it, Hash comparison using == checks
> not only the key value pairs, but also the default value / default
> procs.
>
> So how does one compare 2 hashes key-value pairs. I can see that it
> might be useful to distinguish between 2 hashes whose key-value pairs
> are the same but the default value/default proc are different, but I
> would think that would be much less often than wanting to know if the
> key-value pairs are the same.


I posted this in another thread, but I figured I should dup it here:

for two hashes a and b:

a.sort = b.sort

It converts them to arrays, and sorts them. This should do it.

> Maybe I am thinking about this all wrong, but I always viewed a Hash
> as a Hash, and yes some might have a default value and some might
> have a default proc, but it is the data (the key-value pairs) that,
> to me, make up the Hash. The default data/procs are convenience that
> make it easier to work with a Hash, but I would think that {} and
> Hash.new(3) would be == if their key-value pairs would be equal.


I agree that the way == works with hashes seems strange; I would expect
it to just compare keys/values. OTOH, I can see how some might feel
default values are an important part of determining equality.

cheers,
--Mark



 
Reply With Quote
 
Florian Gross
Guest
Posts: n/a
 
      04-15-2004
wrote:

This will work:

irb(main):001:0> class Hash
irb(main):002:1> def equal_content?(other)
irb(main):003:2> {}.update(self) == {}.update(other)
irb(main):004:2> end
irb(main):005:1> end
=> nil
irb(main):006:0> hash_a = Hash.new { |h, k| h[k] = rand }
=> {}
irb(main):007:0> hash_a[:foo] = "bar"
=> "bar"
irb(main):008:0> hash_a[:qux] = "quz"
=> "quz"
irb(main):009:0> hash_b = {:foo => "bar", :qux => "quz"}
=> {:foo=>"bar", :qux=>"quz"}
irb(main):010:0> hash_a.equal_content?(hash_b)
=> true
irb(main):011:0> {}.equal_content?( => 1)
=> false

Regards,
Florian Gross
 
Reply With Quote
 
nobu.nokada@softhome.net
Guest
Posts: n/a
 
      04-16-2004
Hi,

At Fri, 16 Apr 2004 02:21:58 +0900,
Elias Athanasopoulos wrote in [ruby-talk:97279]:
> * Change '==' method to compare only key-value pairs.
> * Add Hash#=== method to act like current Hash#==


I feel Hash#=== would test membership, i.e., alias for
Hash#key?.

--
Nobu Nakada


 
Reply With Quote
 
Yukihiro Matsumoto
Guest
Posts: n/a
 
      04-16-2004
Hi,

In message "Re: Hash, ==, key-value comparison"
on 04/04/16, Elias Athanasopoulos <> writes:

|* Change '==' method to compare only key-value pairs.
|* Add Hash#=== method to act like current Hash#==

They are possible options, along with

* add new method (e.g. content_equal?) for membership equality.

I'm not sure which one is the best way to go.

matz.


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Comparison of 2 files and generating the output based on comparison Deepu Perl Misc 1 02-07-2011 03:09 PM
Price Comparison Service. Best Deal. Special Coupon atBest-Price-Comparison.com rapee Digital Photography 0 03-14-2008 06:46 AM
Desktop Graphics Card Comparison Guide Rev. 9.2 Posted! Silverstrand Front Page News 0 08-22-2005 04:08 PM
Good comparison of IE to FireFox security record Tom Betz Firefox 0 05-13-2005 04:54 PM
.Net Comparison LV ASP .Net 4 08-31-2003 09:15 PM



Advertisments