[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

splitting an array into sub_arrays ...need advice

Josselin

3/25/2007 3:45:00 PM

I have an array similar to this example (after sorting it on a[i][1]
and a[i][2])

start_array = [ [1, 1, 1, 0], [2, 1, 1, 0], [3, 1, 1, 0], [4, 1, 2, 0],
[5, 1, 2, 0], [6, 2, 1, 0], [7, 2, 1, 0], [8, 2, 2, 0], [9, 2, 2, 0],
[10, 2, 3, 0] ]

I am trying to split it, into sub_arrays according to similarelements
a[i][1] and a[i][2] ,
to get another array like this one :

resulting_array = [ [[1, 1, 1, 0], [2, 1, 1, 0], [3, 1, 1, 0]] ,
[[4, 1, 2, 0], [5, 1, 2, 0]] , [[6, 2, 1, 0], [7, 2, 1, 0]] , [[8,
2, 2, 1], [9, 2, 2, 0]] , [[10, 2, 3, 0]] ]

-----
herafter is how I proceed.. but I am not sure where I go.. is it not
too complicated (not even saying DRY..)

I am using a[i][3] as a counter, so I can change its value, before
executing the splitting

0.step(start_array.nitems-1, 1) do |i|
start_array[i][3] = 0
end

then, I wrote this method

def count_markers(a)
n = 0
0.step(a.nitems-2, 1) do |i|
if (a[i][1] == a[i+1][1]) && (a[i][2] == a[i+1][2])
n = n+1
a[i][3] = n
else
a[i][3] = n +1
n = 0
end
end
a[a.nitems-1][3] = 1 if a[a.nitems-1][3] == 0
end

so I get a count of the number of elements to put in each sub-array

counted_array = count_markers(start_array)
which gives me :
counted_array => [ [1, 1, 1, 1], [2, 1, 1, 2], [3, 1, 1, 3], [4, 1, 2,
1], [5, 1, 2, 2], [6, 2, 1, 1], [7, 2, 1, 2], [8, 2, 2, 1], [9, 2, 2,
2], [10, 2, 3, 1] ]

now I don't see how to split it to get the resulting array

resulting_array = [ [[1, 1, 1, 0], [2, 1, 1, 0], [3, 1, 1, 0]] ,
[[4, 1, 2, 0], [5, 1, 2, 0]] , [[6, 2, 1, 0], [7, 2, 1, 0]] , [[8,
2, 2, 1], [9, 2, 2, 0]] , [[10, 2, 3, 0]] ]
where resulting_array.nitems = 5

resulting_array[0] = [[1, 1, 1, 0], [2, 1, 1, 0], [3, 1, 1, 0]] ... and so on

4 Answers

Olivier

3/25/2007 5:00:00 PM

0

Le dimanche 25 mars 2007 17:50, Josselin a écrit :
> I have an array similar to this example (after sorting it on a[i][1]
> and a[i][2])
>
> start_array = [ [1, 1, 1, 0], [2, 1, 1, 0], [3, 1, 1, 0], [4, 1, 2, 0],
> [5, 1, 2, 0], [6, 2, 1, 0], [7, 2, 1, 0], [8, 2, 2, 0], [9, 2, 2, 0],
> [10, 2, 3, 0] ]
>
> I am trying to split it, into sub_arrays according to similarelements
> a[i][1] and a[i][2] ,
> to get another array like this one :
>
> resulting_array = [ [[1, 1, 1, 0], [2, 1, 1, 0], [3, 1, 1, 0]] ,
> [[4, 1, 2, 0], [5, 1, 2, 0]] , [[6, 2, 1, 0], [7, 2, 1, 0]] , [[8,
> 2, 2, 1], [9, 2, 2, 0]] , [[10, 2, 3, 0]] ]

There is a way to group objects easily with Enumerable#partition_by, in the
Facets gem.

irb(main):001:0> require 'facets'
irb(main):002:0> require 'enumerable/partition_by'
irb(main):006:0> start_array.partition_by {|ary| ary[1..2]}
=> {[1, 2]=>[[4, 1, 2, 0], [5, 1, 2, 0]], [2, 1]=>[[6, 2, 1, 0], [7, 2, 1,
0]], [1, 1]=>[[1, 1, 1, 0], [2, 1, 1, 0], [3, 1, 1, 0]], [2, 3]=>[[10, 2, 3,
0]], [2, 2]=>[[8, 2, 2, 0], [9, 2, 2, 0]]}

It may help you for what you are trying to do.

--
Olivier Renaud

Josselin

3/25/2007 7:57:00 PM

0

On 2007-03-25 19:00:00 +0200, Olivier Renaud <o.renaud@laposte.net> said:

> Le dimanche 25 mars 2007 17:50, Josselin a écrit :
>> I have an array similar to this example (after sorting it on a[i][1]
>> and a[i][2])
>>
>> start_array = [ [1, 1, 1, 0], [2, 1, 1, 0], [3, 1, 1, 0], [4, 1, 2, 0],
>> [5, 1, 2, 0], [6, 2, 1, 0], [7, 2, 1, 0], [8, 2, 2, 0], [9, 2, 2, 0],
>> [10, 2, 3, 0] ]
>>
>> I am trying to split it, into sub_arrays according to similarelements
>> a[i][1] and a[i][2] ,
>> to get another array like this one :
>>
>> resulting_array = [ [[1, 1, 1, 0], [2, 1, 1, 0], [3, 1, 1, 0]] ,
>> [[4, 1, 2, 0], [5, 1, 2, 0]] , [[6, 2, 1, 0], [7, 2, 1, 0]] , [[8,
>> 2, 2, 1], [9, 2, 2, 0]] , [[10, 2, 3, 0]] ]
>
> There is a way to group objects easily with Enumerable#partition_by, in the
>
> Facets gem.
>
> irb(main):001:0> require 'facets'
> irb(main):002:0> require 'enumerable/partition_by'
> irb(main):006:0> start_array.partition_by {|ary| ary[1..2]}
> => {[1, 2]=>[[4, 1, 2, 0], [5, 1, 2, 0]], [2, 1]=>[[6, 2, 1, 0], [7,
> 2, 1,
> 0]], [1, 1]=>[[1, 1, 1, 0], [2, 1, 1, 0], [3, 1, 1, 0]], [2, 3]=>[[10,
> 2, 3,
> 0]], [2, 2]=>[[8, 2, 2, 0], [9, 2, 2, 0]]}
>
> It may help you for what you are trying to do.

thanks a lot I'll have a look asap

Olivier

3/25/2007 8:29:00 PM

0

Note that partition_by is a simple method with no dependencies. So, you can
just copy/paste this method in your code from facets.rubyforge.org online
documentation. Here it is :

module Enumerable
def partition_by
r = Hash.new{ |h,k| h[k]=[] }
each do |e|
r[ yield(e) ] << e
end
return r
end
end

And then :

require 'enumerator'
start_array.partition_by {|ary| ary[1..2]}.to_enum(:each_value).to_a

--
Olivier Renaud

Josselin

3/27/2007 3:47:00 PM

0

On 2007-03-25 22:28:42 +0200, Olivier Renaud <o.renaud@laposte.net> said:

> Note that partition_by is a simple method with no dependencies. So, you can
> just copy/paste this method in your code from facets.rubyforge.org online
> documentation. Here it is :
>
> module Enumerable
> def partition_by
> r = Hash.new{ |h,k| h[k]=[] }
> each do |e|
> r[ yield(e) ] << e
> end
> return r
> end
> end
>
> And then :
>
> require 'enumerator'
> start_array.partition_by {|ary| ary[1..2]}.to_enum(:each_value).to_a

thanks a lot I got it