Where's the best version of Hash#pass and Hash#block?

P

Phlip

Rubies:

This snippet shows how to pass or block arbitrary subsets of Hashes, by their keys:

http://snippets.dzone.com/posts/show/2178

Those items seem useful, because Hashes are not as set-theoretic as Arrays. I
suspect, for example, one cannot & two Hashes to extract their intersection.

That post is from 2006 - essentially the Neolithic Era!

Where's the best modern version of those methods?
 
T

trans

Rubies:

This snippet shows how to pass or block arbitrary subsets of Hashes, by t= heir keys:

=A0 =A0http://snippets.dzone.com/posts/show/2178

Those items seem useful, because Hashes are not as set-theoretic as Array= s. I
suspect, for example, one cannot & two Hashes to extract their intersecti= on.

That post is from 2006 - essentially the Neolithic Era!

Where's the best modern version of those methods?

From Facets:

def slice(*keep_keys)
h =3D {}
keep_keys.each do |key|
h[key] =3D fetch(key)
end
h
end

def except(*less_keys)
slice(*keys - less_keys)
end


T.
 
P

Phlip

Where's the best modern version of those methods?
From Facets:

Thanks - I guessed as much, but isn't there also another Boost-style library for
Ruby? (Boost is essentially Facets for C++ - a repository of reference
implementations for future Standardization, complete with their implications.)
def slice(*keep_keys)

It's okay, but...

If I already have an array, I have to splat * it in:

my_hash.slice(*array)

Why doesn't slice do the flatten trick here?

keep_keys = [keep_keys].flatten
 
M

Matthias Reitinger

Phlip said:
Where's the best modern version of those methods?

Here's my shot at it:

class Hash
def pass(*keys)
Hash[select {|k,v| keys.include? k}]
end

def block(*keys)
reject {|k,v| keys.include? k}
end
end

-Matthias
 
M

Matthias Reitinger

Phlip said:
def slice(*keep_keys)

It's okay, but...

If I already have an array, I have to splat * it in:

my_hash.slice(*array)

Why doesn't slice do the flatten trick here?

keep_keys = [keep_keys].flatten

It would lead to ambiguities if you additionally allowed passing an
array of keys. Consider:

hsh = { [:eek:ne, :two] => [1, 2], :eek:ne => 1, :two => 2 }
hsh.slice([:eek:ne, :two])

Now what should the last line yield? Both { :eek:ne => 1, :two => 2 } and
{ [:eek:ne, :two] => [1, 2] } would be valid, depending on how you
interpret [:eek:ne, :two] (array of keys vs. single key).

-Matthias
 
P

Phlip

Matthias said:
Here's my shot at it:

class Hash
def pass(*keys)
Hash[select {|k,v| keys.include? k}]
end

def block(*keys)
reject {|k,v| keys.include? k}
end
end

Dude that's so lean I'm tossing facets and going with it. Tx!
 
P

Phlip

Matthias said:
Why doesn't slice do the flatten trick here?

keep_keys = [keep_keys].flatten

It would lead to ambiguities if you additionally allowed passing an
array of keys. Consider:

I had already considered the system that only flattens the first depth, but I
forgot to mention it...
 
T

trans

Matthias said:
Here's my shot at it:
=A0 class Hash
=A0 =A0 def pass(*keys)
=A0 =A0 =A0 Hash[select {|k,v| keys.include? k}]
=A0 =A0 end
=A0 =A0 def block(*keys)
=A0 =A0 =A0 reject {|k,v| keys.include? k}
=A0 =A0 end
=A0 end

Dude that's so lean I'm tossing facets and going with it. Tx!

#pass doesn't seem to work, at least not in 1.8.

More importantly, Facets implementation is the way it is b/c it is
fast. Code elegance is nice, but you won't be looking at the code when
you are using it.

user system total real
except 0.150000 0.010000 0.160000 ( 0.155591)
block 8.870000 0.020000 8.890000 ( 8.892466)

T.
 
M

Matthias Reitinger

Thomas said:
#pass doesn't seem to work, at least not in 1.8.

Oops, my fault. I wasn't aware of the fact that I tested it only with
Ruby 1.8.7 (it works there). With Ruby 1.8.6 it fails miserably.
More importantly, Facets implementation is the way it is b/c it is
fast. Code elegance is nice, but you won't be looking at the code when
you are using it.

I must admit that execution speed wasn't one of my priorities for this
snippet. But your point is very valid--I'd also recommend sticking with
the Facets implementation if speed is of any concern.

-Matthias
 
P

Phlip

Oops, my fault. I wasn't aware of the fact that I tested it only with
Ruby 1.8.7 (it works there). With Ruby 1.8.6 it fails miserably.

Take off the Hash[].
I must admit that execution speed wasn't one of my priorities for this
snippet. But your point is very valid--I'd also recommend sticking with
the Facets implementation if speed is of any concern.

I needed to slow down my hacking long enough to install facets on our
pairstations, and achieve buy-in, so I will go with this version first.

Also, it's currently only test-side, so speed is slightly less relevant.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top