finding Hash subsets based on key value

E

ee

Hi

Is there a simple way of searching the keys of a Hash to find a subset.
I have a set of keys with two values indicating group and sub-group,
eg:

group_1_item_1
group_2_item_2
group_1_item_2
group_1_item_4
group_2_item_3

I'd like to divide them into groups, but without having to loop through
the entire collection and having to test each key

Regards
Erik
 
M

Martin DeMello

ee said:
Hi

Is there a simple way of searching the keys of a Hash to find a subset.
I have a set of keys with two values indicating group and sub-group,
eg:

group_1_item_1
group_2_item_2
group_1_item_2
group_1_item_4
group_2_item_3

I'd like to divide them into groups, but without having to loop through
the entire collection and having to test each key

You can't get away without testing each key under the hood (this is
intrinsically an O(n) problem), but this should make it syntactically
convenient at least:

hash.partition {|k,v| k =~ /group_1/ }.map {|i| Hash[*i.flatten]}

Enumerable#partition divides your collection into two parts, based on
whether the block returns true or false, so it doesn't scale to more
than two subsets, but for your example it should work nicely.

martin
 
R

Robert Klemme

Martin said:
ee said:
Hi

Is there a simple way of searching the keys of a Hash to find a
subset. I have a set of keys with two values indicating group and
sub-group, eg:

group_1_item_1
group_2_item_2
group_1_item_2
group_1_item_4
group_2_item_3

I'd like to divide them into groups, but without having to loop
through the entire collection and having to test each key

You can't get away without testing each key under the hood (this is
intrinsically an O(n) problem),
Definitely!

but this should make it syntactically
convenient at least:

hash.partition {|k,v| k =~ /group_1/ }.map {|i| Hash[*i.flatten]}

Enumerable#partition divides your collection into two parts, based on
whether the block returns true or false, so it doesn't scale to more
than two subsets, but for your example it should work nicely.

IMHO we should have a general partitioning method (probably in Enumerable)
that does partitioning into several buckets and not just two. Something
like this maybe:

module Enumerable
def general_partition
parts = Hash.new {|h,k| h[k] = self.class.new}
each do |x|
parts[yield(x)] << x
end
parts
end
end

class Hash
def << (x) self[x[0]] = x[1] end
end
=> {0=>{3=>3}, 1=>{1=>1}, 2=>{2=>2}}

Opinions?

Kind regards

robert
 
M

Martin DeMello

Robert Klemme said:
IMHO we should have a general partitioning method (probably in Enumerable)
that does partitioning into several buckets and not just two. Something
like this maybe:

module Enumerable
def general_partition

I like it, but not the name. partition_by, perhaps.

martin
 
J

James Edward Gray II

Yes, this is *much* better!

The Set class has this feature and I even like the name:

irb(main):001:0> require "set"
=> true
irb(main):002:0> langs = Set.new([:perl, :python, :ruby])
=> #<Set: {:perl, :python, :ruby}>
irb(main):003:0> langs.classify { |m| m.to_s[0, 1] }
=> {"p"=>#<Set: {:perl, :python}>, "r"=>#<Set: {:ruby}>}

James Edward Gray II
 
M

Martin DeMello

James Edward Gray II said:
The Set class has this feature and I even like the name:

irb(main):001:0> require "set"
=> true
irb(main):002:0> langs = Set.new([:perl, :python, :ruby])
=> #<Set: {:perl, :python, :ruby}>
irb(main):003:0> langs.classify { |m| m.to_s[0, 1] }
=> {"p"=>#<Set: {:perl, :python}>, "r"=>#<Set: {:ruby}>}

That *is* nice - wonder if there'd be any issues with moving it into
Enumerable.

martin
 
M

mark

....gonna launch a computerized weather balloon, of couse!

And of course, I need to write the flight control software in Ruby,
because it is my favourite language. Anyone know how to control a
digital camera from ruby (under linux...)

Or, failing that, how to talk to a gps receiver? I'll need to
communicate with muxes as well.

Thanks,

Mark

http://www.retrobbs.org/balloon
 
P

Pit Capitain

Martin said:
irb(main):002:0> langs = Set.new([:perl, :python, :ruby])
=> #<Set: {:perl, :python, :ruby}>
irb(main):003:0> langs.classify { |m| m.to_s[0, 1] }
=> {"p"=>#<Set: {:perl, :python}>, "r"=>#<Set: {:ruby}>}

That *is* nice - wonder if there'd be any issues with moving it into
Enumerable.

Note that Set#classify creates a set for each group, which might not
always be what you want. IMO, Enumerable#classify should create arrays
instead.

Regards,
Pit
 
M

Martin DeMello

Pit Capitain said:
Note that Set#classify creates a set for each group, which might not
always be what you want. IMO, Enumerable#classify should create arrays
instead.

I like Robert Klemme's implementation, where each Enumerable creates
partitions of its own type, and calls << on them to populate them. OTOH
it adds an additional dependency to Enumerable (<< as well as each), but
maybe it could default to Array if << doesn't exist.

martin
 
H

Hal Fulton

mark said:
....gonna launch a computerized weather balloon, of couse!

And of course, I need to write the flight control software in Ruby,
because it is my favourite language. Anyone know how to control a
digital camera from ruby (under linux...)

Or, failing that, how to talk to a gps receiver? I'll need to
communicate with muxes as well.

I can't help you offhand, but I just wanted to say this is the
coolest thing I've heard of in a month or more.

Actually, as for controlling devices... you might look into the
home automation realm. There are some Linux-based solutions there,
probably including security cameras and such.


Hal
 
J

Jeffrey Moss

Most of the cheap devices use serial/RS232 or I2C communications, you'll may
want to look into the realm of microcontrollers for your project. There are
a lot of hobbyists who've written kernel modules and such for these GPS
modules.

Check this out: www.gumstix.org

I found that gumstix board a while back and decided to dive right in to the
realm of microcontrollers. Never tried compiling ruby on it, don't know how
easy that would be, maybe others have done it.

-Jeff

----- Original Message -----
From: "Hal Fulton" <[email protected]>
To: "ruby-talk ML" <[email protected]>
Sent: Tuesday, June 14, 2005 5:18 PM
Subject: Re: Crazy Balloon flight computer software...
 

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

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,015
Latest member
AmbrosePal

Latest Threads

Top