Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > [GOLF]: partitioning an array

Reply
Thread Tools

[GOLF]: partitioning an array

 
 
Max Muermann
Guest
Posts: n/a
 
      12-07-2006
Take an array of objects and partition it into subarrays, based on
some arbitrary property of the objects. I would use this for example
for generating a report of purchase orders and grouped by week, month,
year, approximate value, etc.

The idea is similar to Array#partition, but where partition only does
a true/false check, the resulting array should be partitioned by the
return value of a block so that:

a = ['a','bc','def','g','hi','jkl','m']
group(a) {|i| i.size} #=> [["a", "g", "m"], ["bc", "hi"], ["def", "jkl"]]


My best effort so far is this:

def group array, &block
h = {}
array.each do |e|
(h[yield(e)]||=[])<<e
end
h.to_a.map {|e| e[1] }
end

For some reason, I cannot bring myself to like this. I have the
nagging feeling that there is a more elegant way...

Cheers,
Max

 
Reply With Quote
 
 
 
 
ara.t.howard@noaa.gov
Guest
Posts: n/a
 
      12-07-2006
On Thu, 7 Dec 2006, Max Muermann wrote:

> Take an array of objects and partition it into subarrays, based on
> some arbitrary property of the objects. I would use this for example
> for generating a report of purchase orders and grouped by week, month,
> year, approximate value, etc.
>
> The idea is similar to Array#partition, but where partition only does
> a true/false check, the resulting array should be partitioned by the
> return value of a block so that:
>
> a = ['a','bc','def','g','hi','jkl','m']
> group(a) {|i| i.size} #=> [["a", "g", "m"], ["bc", "hi"], ["def", "jkl"]]
>
>
> My best effort so far is this:
>
> def group array, &block
> h = {}
> array.each do |e|
> (h[yield(e)]||=[])<<e
> end
> h.to_a.map {|e| e[1] }
> end
>
> For some reason, I cannot bring myself to like this. I have the
> nagging feeling that there is a more elegant way...
>
> Cheers,
> Max


it's not a good golf solution, but here's a slightly differnet approach:

harp:~ > cat a.rb
module Enumerable
def group_by &b
h = Hash.new{|h,k| h[k] = []}
each{|x| h[x.instance_eval(&b)] << x}
h.values
end
end

a = %w[ a bc def g hi jkl m ]
p a.group_by{ size }


h = { 'k' => 'v', 'K' => 'V', 'a' => 'b', 'A' => 'b' }
p h.group_by{ first.downcase }


harp:~ > ruby a.rb
[["a", "g", "m"], ["bc", "hi"], ["def", "jkl"]]
[[["K", "V"], ["k", "v"]], [["A", "b"], ["a", "b"]]]


regards.



-a
--
if you want others to be happy, practice compassion.
if you want to be happy, practice compassion. -- the dalai lama

 
Reply With Quote
 
 
 
 
Robert Klemme
Guest
Posts: n/a
 
      12-07-2006
On 07.12.2006 09:46, Ross Bamford wrote:
> On Thu, 07 Dec 2006 03:46:37 -0000, Max Muermann <(E-Mail Removed)> wrote:
>
>> Take an array of objects and partition it into subarrays, based on
>> some arbitrary property of the objects. I would use this for example
>> for generating a report of purchase orders and grouped by week, month,
>> year, approximate value, etc.
>>
>> The idea is similar to Array#partition, but where partition only does
>> a true/false check, the resulting array should be partitioned by the
>> return value of a block so that:
>>
>> a = ['a','bc','def','g','hi','jkl','m']
>> group(a) {|i| i.size} #=> [["a", "g", "m"], ["bc", "hi"], ["def", "jkl"]]
>>
>>
>> My best effort so far is this:
>>
>> def group array, &block
>> h = {}
>> array.each do |e|
>> (h[yield(e)]||=[])<<e
>> end
>> h.to_a.map {|e| e[1] }


The last line is definitively superfluous in the light of Hash#values.

>> end
>>
>> For some reason, I cannot bring myself to like this. I have the
>> nagging feeling that there is a more elegant way...

>
> Maybe:
>
> a = ['a','bc','def','g','hi','jkl','m']
> # => ["a", "bc", "def", "g", "hi", "jkl", "m"]
>
> a.inject([]){|dst,e|(dst[e.length-1]||=[])<<e;dst}
> # => [["a", "g", "m"], ["bc", "hi"], ["def", "jkl"]]


But:

>> %w{a bbb}.inject([]){|dst,e|(dst[e.length-1]||=[])<<e;dst}

=> [["a"], nil, ["bbb"]]

I did

>> a = ['a','bc','def','g','hi','jkl','m']

=> ["a", "bc", "def", "g", "hi", "jkl", "m"]
>> a.inject(Hash.new {|h,k| h[k]=[]}) {|r,x| r[x.size] << x; r}.values

=> [["a", "g", "m"], ["bc", "hi"], ["def", "jkl"]]

>> %w{a bbb}.inject(Hash.new {|h,k| h[k]=[]}) {|r,x| r[x.size] << x;

r}.values
=> [["a"], ["bbb"]]

Whether that's nicer - I don't know.

Kind regards

robert
 
Reply With Quote
 
Martin DeMello
Guest
Posts: n/a
 
      12-07-2006
On 12/7/06, Robert Klemme <(E-Mail Removed)> wrote:
> Hash.new {|h,k| h[k]=[]}


This is common enough that it deserves to be its own constructor, imo
- Hash.multi perhaps

martin

 
Reply With Quote
 
Dave Burt
Guest
Posts: n/a
 
      12-07-2006
Martin DeMello wrote:
> On 12/7/06, Robert Klemme <(E-Mail Removed)> wrote:
>> Hash.new {|h,k| h[k]=[]}

>
> This is common enough that it deserves to be its own constructor, imo
> - Hash.multi perhaps


Would you want one of these, too?

class Hash
def self.new_nested
f = proc {|h, k| h[k] = new(&f) }
new(&f)
end
end

Cheers,
Dave
 
Reply With Quote
 
ara.t.howard@noaa.gov
Guest
Posts: n/a
 
      12-07-2006
On Thu, 7 Dec 2006, Martin DeMello wrote:

> On 12/7/06, Robert Klemme <(E-Mail Removed)> wrote:
>> Hash.new {|h,k| h[k]=[]}

>
> This is common enough that it deserves to be its own constructor, imo
> - Hash.multi perhaps


my own lib has

def Hash.list list_class = Array, *a, &b
Hash.new {|h,k| h[k] = list_class.new(*a, &b)}
end


-a
--
if you want others to be happy, practice compassion.
if you want to be happy, practice compassion. -- the dalai lama

 
Reply With Quote
 
Trans
Guest
Posts: n/a
 
      12-07-2006

http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> On Thu, 7 Dec 2006, Martin DeMello wrote:
>
> > On 12/7/06, Robert Klemme <(E-Mail Removed)> wrote:
> >> Hash.new {|h,k| h[k]=[]}

> >
> > This is common enough that it deserves to be its own constructor, imo
> > - Hash.multi perhaps

>
> my own lib has
>
> def Hash.list list_class = Array, *a, &b
> Hash.new {|h,k| h[k] = list_class.new(*a, &b)}
> end


def Hash.new_by(o='[]')
Hash.new {|h,k| h[k] = eval o}
end

Hash.new_by '[]'

T.


 
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
Application "partitioning" BobRoyAce ASP .Net 2 01-24-2005 09:24 PM
Re: partitioning Sartan Dragonbane MCSE 0 04-30-2004 05:29 AM
Re: partitioning Kendal Emery MCSE 2 04-29-2004 09:32 PM
Re: partitioning billyw MCSE 9 04-29-2004 08:29 PM
partitioning no one MCSE 0 04-29-2004 07:02 PM



Advertisments