[prev in list] [next in list] [prev in thread] [next in thread] 

List:       ruby-talk
Subject:    Re: !x.include? y
From:       "Phrogz" <gavin () refinery ! com>
Date:       2006-10-31 18:30:12
Message-ID: 1162319131.725466.224930 () m7g2000cwm ! googlegroups ! com
[Download RAW message or body]

Giles Bowkett wrote:
> basically, I need to filter list A to match list B. list A is a list
> of objects with a particular field, and list B is a list of acceptable
> values for that field.

Interesting; you're basically talking about set intersection:
irb(main):001:0> requested = %w|a b c x z|
=> ["a", "b", "c", "x", "z"]
irb(main):002:0> legal = %w|a b c d e f g|
=> ["a", "b", "c", "d", "e", "f", "g"]
irb(main):003:0> requested & legal
=> ["a", "b", "c"]

Except that you're talking about calling considering an object
equivalent to the value of one of its 'fields'. I had hoped that the
following would work, but no luck:
  class Object
    def equiv; self; end
  end

  class Equiv
    def self.[]( data, equiv )
      self.new( data, equiv )
    end
    attr_accessor :data, :equiv
    def initialize( data, equiv )
      @data, @equiv = data, equiv
    end
    def <=>( o2 ); @equiv <=> o2.equiv;    end
    def == ( o2 ); @equiv == o2.equiv;     end
    def ===( o2 ); @equiv === o2.equiv;    end
    def eq?( o2 ); @equiv.eq?( o2.equiv ); end
    def hash;      @equiv.hash              end
  end

  possible = [
    Equiv[ 1001, 'a' ],
    Equiv[ 1002, 'b' ],
    Equiv[ 1003, 'c' ],
    Equiv[ 2098, 'x' ],
    Equiv[ 3143, 'z' ]
  ]
  legal = %w|a b c d e f g|

  p possible & legal
  #=> []

Looking at the source code for Array#&, I see that it uses the hash
value of at least one of the arrays. (And I can see that my custom hash
method above is getting called.) But that's not enough. Apparently I
can't even *read* C code any more, much less write it.

Can someone who is more C savvy than I am tell me what the following
code is doing (and thus what might be done, if anything, to allow the
built-in Array#& to work with custom classes pretending to be something
they aren't)?

static VALUE
rb_ary_and(ary1, ary2)
    VALUE ary1, ary2;
{
    VALUE hash, ary3, v, vv;
    long i;

    ary2 = to_ary(ary2);
    ary3 = rb_ary_new2(RARRAY(ary1)->len < RARRAY(ary2)->len ?
	    RARRAY(ary1)->len : RARRAY(ary2)->len);
    hash = ary_make_hash(ary2, 0);

    for (i=0; i<RARRAY(ary1)->len; i++) {
	v = vv = rb_ary_elt(ary1, i);
	if (st_delete(RHASH(hash)->tbl, (st_data_t*)&vv, 0)) {
	    rb_ary_push(ary3, v);
	}
    }

    return ary3;
}


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic