Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

finding Hash subsets based on key value

219 views
Skip to first unread message

ee

unread,
Jun 12, 2005, 6:56:06 PM6/12/05
to
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

Nura...@aol.com

unread,
Jun 12, 2005, 7:07:13 PM6/12/05
to
Hello,

maybe it's not the most elegant solution, but I'd create copies of the
original hash
for the subgroups and use the delete_if method for hashes to throw out
everything
that does not belong to group number n..

Best regards,

Axel


Martin DeMello

unread,
Jun 13, 2005, 12:18:33 AM6/13/05
to

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

Robert Klemme

unread,
Jun 13, 2005, 3:37:36 AM6/13/05
to
Martin DeMello wrote:
> ee <erik...@gmail.com> wrote:
>> 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

>> h={1=>1,2=>2,3=>3}
=> {1=>1, 2=>2, 3=>3}
>> h.general_partition {|k,v| k % 3}
=> {0=>{3=>3}, 1=>{1=>1}, 2=>{2=>2}}

Opinions?

Kind regards

robert

Martin DeMello

unread,
Jun 13, 2005, 4:41:16 AM6/13/05
to
Robert Klemme <bob....@gmx.net> wrote:
>
> 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

Robert Klemme

unread,
Jun 13, 2005, 4:51:50 AM6/13/05
to

Yes, this is *much* better!

robert

James Edward Gray II

unread,
Jun 13, 2005, 9:09:45 AM6/13/05
to

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

Martin DeMello

unread,
Jun 14, 2005, 5:32:52 AM6/14/05
to
James Edward Gray II <ja...@grayproductions.net> wrote:
>
> 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

mark

unread,
Jun 14, 2005, 5:44:00 AM6/14/05
to
...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

Pit Capitain

unread,
Jun 14, 2005, 5:48:54 AM6/14/05
to
Martin DeMello schrieb:

>>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


Martin DeMello

unread,
Jun 14, 2005, 5:59:12 AM6/14/05
to
Pit Capitain <p...@capitain.de> wrote:
>
> 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

Hal Fulton

unread,
Jun 14, 2005, 7:18:43 PM6/14/05
to
mark wrote:
> ....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

nobuyoshi nakada

unread,
Jun 15, 2005, 12:02:51 AM6/15/05
to
Hi,

At Tue, 14 Jun 2005 18:44:00 +0900,
mark wrote in [ruby-talk:145336]:


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

I often use gpstrans on Linux.
<http://sourceforge.net/projects/gpstrans/>

--
Nobu Nakada


Steven Jenkins

unread,
Jun 15, 2005, 1:31:57 AM6/15/05
to
Hal Fulton wrote:
> mark wrote:
>
>> ....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.

Ham radio geeks have been at this for a while:
http://users.crosspaths.net/~wallio/HABLinks.html

Also check out APRS: http://web.usna.navy.mil/~bruninga/aprs.html

Steve (N6UNI)


mark

unread,
Jun 15, 2005, 6:09:56 AM6/15/05
to
Thanks for the info! I'll check that out!

mark

unread,
Jun 15, 2005, 6:09:33 AM6/15/05
to
Thanks. I wish I could say I thought of it, but I didn't. I stumbled
across the idea on the net, when I was looking for something to do to
remember a friend of mine who died. He would have loved the idea.

I'll have a look at the automation stuff. I need to be able to read gps
data, and send it back out over a TNC to a 2meter ham radio, so I can
find the darn thing again. I also need to be able to record still
pictures from a digital camera and record a movie from a webcam... all
without resorting to xwindows if possible... as I plan to run under
linux booting into console mode... with no monitor.

Thanks for the kind words!

Mark

Oh ya, the start of a website is at http://www.retrobbs.org/balloon


-----Original Message-----
From: Hal Fulton [mailto:hal...@hypermetrics.com]
Sent: 15 June 2005 00:19
To: ruby-talk ML
Subject: Re: Crazy Balloon flight computer software...

mark

unread,
Jun 15, 2005, 6:11:39 AM6/15/05
to
Very true, they have been doing it for years, in the Untied States, but
after googling for days, I can't find anyone in the UK who is doing
this. Maybe it is because the balloons end up in the Atlantic, very
much a worry for me.

If anyone has any info on this in the UK (I know this is getting off
topic) I'd sure appreciate it.

Thanks for the links!

Mark

Jeffrey Moss

unread,
Jun 15, 2005, 11:42:37 AM6/15/05
to
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" <hal...@hypermetrics.com>
To: "ruby-talk ML" <ruby...@ruby-lang.org>
Sent: Tuesday, June 14, 2005 5:18 PM
Subject: Re: Crazy Balloon flight computer software...

0 new messages