Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > Grouping elements of an array

Reply
Thread Tools

Grouping elements of an array

 
 
Steve Wilhelm
Guest
Posts: n/a
 
      03-18-2010
I have an array of records that contain timestamps at random intervals.
The records are ordered by timestamp.

I would like to convert the array into an array of arrays; each subarray
would contain "grouped records." Grouping would occur if the timestamp
of the next element in the original array is within thirty seconds of
the current element.

Example (second column is timestamp in seconds starting from zero).

A 0
B 15
C 35
D 100
E 205
F 215
G 300

would result in

[[A, B, C], [D], [E, F], [G]]

Any help on how to do this in the "Ruby Way" would be appreciated.

- Steve W.
--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
 
 
 
Josh Cheek
Guest
Posts: n/a
 
      03-19-2010
[Note: parts of this message were removed to make it a legal post.]

On Thu, Mar 18, 2010 at 4:50 PM, Steve Wilhelm <(E-Mail Removed)> wrote:

> I have an array of records that contain timestamps at random intervals.
> The records are ordered by timestamp.
>
> I would like to convert the array into an array of arrays; each subarray
> would contain "grouped records." Grouping would occur if the timestamp
> of the next element in the original array is within thirty seconds of
> the current element.
>
> Example (second column is timestamp in seconds starting from zero).
>
> A 0
> B 15
> C 35
> D 100
> E 205
> F 215
> G 300
>
> would result in
>
> [[A, B, C], [D], [E, F], [G]]
>
> Any help on how to do this in the "Ruby Way" would be appreciated.
>
> - Steve W.
> --
> Posted via http://www.ruby-forum.com/.
>
>

What about
A 0
B 20
C 40

Does that become
[[A,B],[B,C]] or [[A,B,C]] or something else? The congruence class here is
unclear.

 
Reply With Quote
 
 
 
 
Steve Wilhelm
Guest
Posts: n/a
 
      03-19-2010
Josh Cheek wrote:
> On Thu, Mar 18, 2010 at 4:50 PM, Steve Wilhelm <(E-Mail Removed)>
> wrote:
>
>> A 0
>>
>> Any help on how to do this in the "Ruby Way" would be appreciated.
>>
>> - Steve W.
>> --
>> Posted via http://www.ruby-forum.com/.
>>
>>

> What about
> A 0
> B 20
> C 40
>
> Does that become
> [[A,B],[B,C]] or [[A,B,C]] or something else? The congruence class here
> is
> unclear.


It would be [[A,B,C]].

- Steve W.
--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
Roger Braun
Guest
Posts: n/a
 
      03-19-2010
Hi

On Thu, Mar 18, 2010 at 11:50 PM, Steve Wilhelm <(E-Mail Removed)> wrote:
> I have an array of records that contain timestamps at random intervals.
> The records are ordered by timestamp.
>
> I would like to convert the array into an array of arrays; each subarray
> would contain "grouped records." Grouping would occur if the timestamp
> of the next element in the original array is within thirty seconds of
> the current element.
>
> Example (second column is timestamp in seconds starting from zero).
>
> A 0
> B 15
> C 35
> D 100
> E 205
> F 215
> G 300
>
> would result in
>
> [[A, B, C], [D], [E, F], [G]]
>
> Any help on how to do this in the "Ruby Way" would be appreciated.


How about this:

1 arr = [0,15,35,100,205,300]
2 arr2 = [0, 20, 40]
3
4 def group(array)
5 array.map!{|e| [e]}
6 array.inject([]) do |r, e|
7 if r == [] or e[0] - r.last.last > 30 then
8 r.push(e)
9 else
10 r[-1].push(e[0])
11 end
12 r
13 end
14 end
15
16 puts arr.inspect
17 puts group(arr).inspect
18 puts arr2.inspect
19 puts group(arr2).inspect

--
Roger Braun
http://yononaka.de
http://www.velocityreviews.com/forums/(E-Mail Removed)-tuebingen.de

 
Reply With Quote
 
Josh Cheek
Guest
Posts: n/a
 
      03-19-2010
[Note: parts of this message were removed to make it a legal post.]

On Thu, Mar 18, 2010 at 4:50 PM, Steve Wilhelm <(E-Mail Removed)> wrote:

> I have an array of records that contain timestamps at random intervals.
> The records are ordered by timestamp.
>
> I would like to convert the array into an array of arrays; each subarray
> would contain "grouped records." Grouping would occur if the timestamp
> of the next element in the original array is within thirty seconds of
> the current element.
>
> Example (second column is timestamp in seconds starting from zero).
>
> A 0
> B 15
> C 35
> D 100
> E 205
> F 215
> G 300
>
> would result in
>
> [[A, B, C], [D], [E, F], [G]]
>
> Any help on how to do this in the "Ruby Way" would be appreciated.
>
> - Steve W.
> --
> Posted via http://www.ruby-forum.com/.
>
>

Here is my solution, it's conceptually similar to Roger's, though differs in
implementation http://gist.github.com/337195

 
Reply With Quote
 
Josh Cheek
Guest
Posts: n/a
 
      03-19-2010
[Note: parts of this message were removed to make it a legal post.]

On Thu, Mar 18, 2010 at 9:29 PM, Urabe Shyouhei <(E-Mail Removed)>wrote:

> Roger Braun wrote:
> > How about this:

>
> You should really know about Enumerable#group_by.
>
> irb(main):001:0> [0,15,35,100,205,300].group_by {|i| i/100 }
> => {0=>[0, 15, 35], 1=>[100], 2=>[205], 3=>[300]}
>
>
>

Your results are correct only because of a happenstance of the data. Add 99
in there, it should group with 100, but it groups with the 0...100
congruence class

ruby-1.9.1-p378 > [0,15,35,99,100,205,300].group_by {|i| i/100 }
=> {0=>[0, 15, 35, 99], 1=>[100], 2=>[205], 3=>[300]}

Because these groups are relative to each other, I think you must do
something like Roger or I did, where you iterate through the list and
compare it to the groups.

 
Reply With Quote
 
Roger Braun
Guest
Posts: n/a
 
      03-19-2010
On Fri, Mar 19, 2010 at 4:29 AM, Urabe Shyouhei <(E-Mail Removed)> wrote:
> Roger Braun wrote:
>> How about this:

>
> You should really know about Enumerable#group_by.
>
> irb(main):001:0> [0,15,35,100,205,300].group_by {|i| i/100 }
> => {0=>[0, 15, 35], 1=>[100], 2=>[205], 3=>[300]}


This does not solve the problem.

irb(main):011:0> [0,15,35,99,100,205,300].group_by{|i| i/100}
=> {0=>[0, 15, 35, 99], 1=>[100], 2=>[205], 3=>[300]}

but should be

[[0, 15, 35], [99, 100], [205], [300]]

at least if I understood the problem correctly.

--
Roger Braun
http://yononaka.de
(E-Mail Removed)-tuebingen.de

 
Reply With Quote
 
Robert Klemme
Guest
Posts: n/a
 
      03-19-2010
On 03/18/2010 11:50 PM, Steve Wilhelm wrote:
> I have an array of records that contain timestamps at random intervals.
> The records are ordered by timestamp.
>
> I would like to convert the array into an array of arrays; each subarray
> would contain "grouped records." Grouping would occur if the timestamp
> of the next element in the original array is within thirty seconds of
> the current element.
>
> Example (second column is timestamp in seconds starting from zero).
>
> A 0
> B 15
> C 35
> D 100
> E 205
> F 215
> G 300
>
> would result in
>
> [[A, B, C], [D], [E, F], [G]]
>
> Any help on how to do this in the "Ruby Way" would be appreciated.


Assuming records are ordered already - otherwise you need a sort in between.

require 'pp'

dat = <<DDD.each_line.map {|l|r = l.split;r[1]=r[1].to_i;r}
A 0
B 15
C 35
D 100
E 205
F 215
G 300
DDD

pp dat

gr = dat.inject [] do |agg, rec|
if agg.last && rec[1] - agg.last.last[1] <= 15
agg.last << rec
agg
else
agg << [rec]
end
end

pp gr

Note: I don't claim that this is *the* Ruby way.

Kind regards

robert

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
 
Reply With Quote
 
Steve Wilhelm
Guest
Posts: n/a
 
      03-19-2010
> I have an array of records that...

Thank you all for your solutions.

The time they saved me, I'll spend learning about the techniques you
employed.

- Steve W.

--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
Guest
Posts: n/a
 
      03-19-2010
[Note: parts of this message were removed to make it a legal post.]


Hello, I am new to Ruby. Below is my solution:

a=[0, 15, 35, 100, 205, 215, 300]
b=[]
c=[]
d=a[0]
a.each do |i|
if i - d < 30
c << i
else
b << c
c=[i]
end
d =i
end
if c.size > 0
b << c
end

p b

 
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
Grouping array elements while preserving order? Matt Constantine Ruby 2 09-22-2008 05:27 AM
What's the ruby way of grouping elements of an array? Sam Kong Ruby 5 10-22-2007 03:21 AM
Grouping elements of an array? Sam Kong Ruby 6 01-08-2007 08:12 AM
.Re: Grouping neighboring elements with xsl Dimitre Novatchev XML 0 11-28-2003 08:31 AM
Grouping neighboring elements with xsl kcwolle XML 0 11-27-2003 09:34 PM



Advertisments