array slicing

J

Josselin

given an array

anArray = [["a", 1, 1], ["b", 1, 2], ["c", 1, 5], ["z", 1, 1], ["e", 1,
5], ["f", 1, 6], ["g", 1, 1], ["h", 1, 3], ["i", 1, 1], ["j", 1, 2],
["k", 1, 1], ["y", 1, 6], ["m", 1, 1], ["u", 1, 2], ["v", 1, 1], ["p",
1, 4], ["q", 1, 5], ["r", 1, 1], ["n", 1, 1], ["t", 2, 3], ["s", 2, 2],
["o", 2, 1], ["w", 2, 1], ["x", 2, 1], ["l", 2, 1], ["d", 2, 1]]

I would like to get it sliced in groups of element having the same 2nd
and 3rd values

sliced_array = [
[ ["a", 1, 1],["g", 1, 1], ["i", 1, 1], ["k", 1, 1], ["m", 1, 1], ["n",
1, 1],["r", 1, 1],["v", 1, 1],["z", 1, 1] ],
[ ["b", 1, 2],["j", 1, 2], ["u", 1, 2] ],
[ ["c", 1, 5],["e", 1, 5],["q", 1, 5] ],
[ ["d", 2, 1],["l", 2, 1], ["l", 2, 1], ["o", 2, 1],["w", 2, 1],["x", 2, 1] ],
[ ["f", 1, 6],["y", 1, 6] ],
[ ["h", 1, 3] ],
[ ["p", 1, 4] ],
[ ["s", 2, 2] ],
[ ["t", 2, 3] ]
]

I believe teh first step is to sort anArray.... then slicing similar
groups, but writing
anArray.sort {|a,b| a[1] <=> b[1]}
sorts only on first value... how can I sort on both.. ?

thansk

joss
 
J

Josselin

given an array

anArray = [["a", 1, 1], ["b", 1, 2], ["c", 1, 5], ["z", 1, 1], ["e", 1,
5], ["f", 1, 6], ["g", 1, 1], ["h", 1, 3], ["i", 1, 1], ["j", 1, 2],
["k", 1, 1], ["y", 1, 6], ["m", 1, 1], ["u", 1, 2], ["v", 1, 1], ["p",
1, 4], ["q", 1, 5], ["r", 1, 1], ["n", 1, 1], ["t", 2, 3], ["s", 2, 2],
["o", 2, 1], ["w", 2, 1], ["x", 2, 1], ["l", 2, 1], ["d", 2, 1]]

I would like to get it sliced in groups of element having the same 2nd
and 3rd values

sliced_array = [
[ ["a", 1, 1],["g", 1, 1], ["i", 1, 1], ["k", 1, 1], ["m", 1, 1], ["n",
1, 1],["r", 1, 1],["v", 1, 1],["z", 1, 1] ],
[ ["b", 1, 2],["j", 1, 2], ["u", 1, 2] ],
[ ["c", 1, 5],["e", 1, 5],["q", 1, 5] ],
[ ["d", 2, 1],["l", 2, 1], ["l", 2, 1], ["o", 2, 1],["w", 2, 1],["x", 2, 1] ],
[ ["f", 1, 6],["y", 1, 6] ],
[ ["h", 1, 3] ],
[ ["p", 1, 4] ],
[ ["s", 2, 2] ],
[ ["t", 2, 3] ]
]

I believe teh first step is to sort anArray.... then slicing similar
groups, but writing
anArray.sort {|a,b| a[1] <=> b[1]}
sorts only on first value... how can I sort on both.. ?

thansk

joss

found the sort... but how to slice it now ?
anArray.sort_by {|item| [item[1], item[2] ] }
=> [["a", 1, 1], ["z", 1, 1], ["v", 1, 1], ["r", 1, 1], ["i", 1, 1],
["m", 1, 1], ["g", 1, 1], ["k", 1, 1], ["n", 1, 1], ["j", 1, 2], ["u",
1, 2], ["b", 1, 2], ["h", 1, 3], ["p", 1, 4], ["c", 1, 5], ["e", 1, 5],
["q", 1, 5], ["f", 1, 6], ["y", 1, 6], ["l", 2, 1], ["x", 2, 1], ["o",
2, 1], ["w", 2, 1], ["d", 2, 1], ["s", 2, 2], ["t", 2, 3]]

["a", 1, 1], ["z", 1, 1], ["v", 1, 1], ["r", 1, 1], ["i", 1, 1], ["m",
1, 1], ["g", 1, 1], ["k", 1, 1]
["j", 1, 2], ["u", 1, 2], ["b", 1, 2]
and so on....

??? thanks
joss
 
J

Josselin

given an array

anArray = [["a", 1, 1], ["b", 1, 2], ["c", 1, 5], ["z", 1, 1], ["e", 1,
5], ["f", 1, 6], ["g", 1, 1], ["h", 1, 3], ["i", 1, 1], ["j", 1, 2],
["k", 1, 1], ["y", 1, 6], ["m", 1, 1], ["u", 1, 2], ["v", 1, 1], ["p",
1, 4], ["q", 1, 5], ["r", 1, 1], ["n", 1, 1], ["t", 2, 3], ["s", 2, 2],
["o", 2, 1], ["w", 2, 1], ["x", 2, 1], ["l", 2, 1], ["d", 2, 1]]

I would like to get it sliced in groups of element having the same 2nd
and 3rd values

sliced_array = [
[ ["a", 1, 1],["g", 1, 1], ["i", 1, 1], ["k", 1, 1], ["m", 1, 1], ["n",
1, 1],["r", 1, 1],["v", 1, 1],["z", 1, 1] ],
[ ["b", 1, 2],["j", 1, 2], ["u", 1, 2] ],
[ ["c", 1, 5],["e", 1, 5],["q", 1, 5] ],
[ ["d", 2, 1],["l", 2, 1], ["l", 2, 1], ["o", 2, 1],["w", 2, 1],["x", 2, 1] ],
[ ["f", 1, 6],["y", 1, 6] ],
[ ["h", 1, 3] ],
[ ["p", 1, 4] ],
[ ["s", 2, 2] ],
[ ["t", 2, 3] ]
]

I believe teh first step is to sort anArray.... then slicing similar
groups, but writing
anArray.sort {|a,b| a[1] <=> b[1]}
sorts only on first value... how can I sort on both.. ?

thansk

joss

found the sort... but how to slice it now ?
anArray.sort_by {|item| [item[1], item[2] ] }
=> [["a", 1, 1], ["z", 1, 1], ["v", 1, 1], ["r", 1, 1], ["i", 1, 1],
["m", 1, 1], ["g", 1, 1], ["k", 1, 1], ["n", 1, 1], ["j", 1, 2], ["u",
1, 2], ["b", 1, 2], ["h", 1, 3], ["p", 1, 4], ["c", 1, 5], ["e", 1, 5],
["q", 1, 5], ["f", 1, 6], ["y", 1, 6], ["l", 2, 1], ["x", 2, 1], ["o",
2, 1], ["w", 2, 1], ["d", 2, 1], ["s", 2, 2], ["t", 2, 3]]

["a", 1, 1], ["z", 1, 1], ["v", 1, 1], ["r", 1, 1], ["i", 1, 1], ["m",
1, 1], ["g", 1, 1], ["k", 1, 1]
["j", 1, 2], ["u", 1, 2], ["b", 1, 2]
and so on....

??? thanks
joss

found a reply from ... (thanks to him...)


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'
sArray = anArray.sort_by {|item| [item[1], item[2] ] }

sArray.partition_by {|ary| ary[1..2]}.to_enum:)each_value).to_a=>
[[["j", 1, 2], ["u", 1, 2], ["b", 1, 2]], [["l", 2, 1], ["x", 2, 1],
["o", 2, 1], ["w", 2, 1], ["d", 2, 1]], [["a", 1, 1], ["z", 1, 1],
["v", 1, 1], ["r", 1, 1], ["i", 1, 1], ["m", 1, 1], ["g", 1, 1], ["k",
1, 1], ["n", 1, 1]], [["f", 1, 6], ["y", 1, 6]], [["t", 2, 3]], [["c",
1, 5], ["e", 1, 5], ["q", 1, 5]], [["s", 2, 2]], [["p", 1, 4]], [["h",
1, 3]]]

and that's it.....
 
P

Peña, Botp

from: Josselin [mailto:[email protected]] :
# anArray.sort {|a,b| a[1] <=3D> b[1]}
# sorts only on first value... how can I sort on both.. ?

try sort_by

irb(main):020:0> a=3D[["a", 3, 3], ["c", 1, 5], ["b", 1, 2],["d",3,1]]
=3D> [["a", 3, 3], ["c", 1, 5], ["b", 1, 2], ["d", 3, 1]]
irb(main):021:0> a.sort_by {|x| [x[1],x[2]]}
=3D> [["b", 1, 2], ["c", 1, 5], ["d", 3, 1], ["a", 3, 3]]
 
H

Harry Kakueki

given an array

anArray = [["a", 1, 1], ["b", 1, 2], ["c", 1, 5], ["z", 1, 1], ["e", 1,
5], ["f", 1, 6], ["g", 1, 1], ["h", 1, 3], ["i", 1, 1], ["j", 1, 2],
["k", 1, 1], ["y", 1, 6], ["m", 1, 1], ["u", 1, 2], ["v", 1, 1], ["p",
1, 4], ["q", 1, 5], ["r", 1, 1], ["n", 1, 1], ["t", 2, 3], ["s", 2, 2],
["o", 2, 1], ["w", 2, 1], ["x", 2, 1], ["l", 2, 1], ["d", 2, 1]]

I would like to get it sliced in groups of element having the same 2nd
and 3rd values

sliced_array = [
[ ["a", 1, 1],["g", 1, 1], ["i", 1, 1], ["k", 1, 1], ["m", 1, 1], ["n",
1, 1],["r", 1, 1],["v", 1, 1],["z", 1, 1] ],
[ ["b", 1, 2],["j", 1, 2], ["u", 1, 2] ],
[ ["c", 1, 5],["e", 1, 5],["q", 1, 5] ],
[ ["d", 2, 1],["l", 2, 1], ["l", 2, 1], ["o", 2, 1],["w", 2, 1],["x", 2, 1] ],
[ ["f", 1, 6],["y", 1, 6] ],
[ ["h", 1, 3] ],
[ ["p", 1, 4] ],
[ ["s", 2, 2] ],
[ ["t", 2, 3] ]
]

I believe teh first step is to sort anArray.... then slicing similar
groups, but writing
anArray.sort {|a,b| a[1] <=> b[1]}
sorts only on first value... how can I sort on both.. ?

thansk

joss

Try this

p anArray.sort {|a,b| a.slice(1..2) <=> b.slice(1..2)}

Harry
 
H

Harry Kakueki

from: Josselin [mailto:[email protected]] :
# anArray.sort {|a,b| a[1] <=3D> b[1]}
# sorts only on first value... how can I sort on both.. ?

try sort_by

irb(main):020:0> a=3D[["a", 3, 3], ["c", 1, 5], ["b", 1, 2],["d",3,1]]
=3D> [["a", 3, 3], ["c", 1, 5], ["b", 1, 2], ["d", 3, 1]]
irb(main):021:0> a.sort_by {|x| [x[1],x[2]]}
=3D> [["b", 1, 2], ["c", 1, 5], ["d", 3, 1], ["a", 3, 3]]

Or this :)

p anArray.sort_by {|x| [x[1],x[2],x[0]]}

Harry

--=20
http://www.kakueki.com/ruby/list.html
A Look into Japanese Ruby List in English
 
H

Harry Kakueki

from: Josselin [mailto:[email protected]] :
# anArray.sort {|a,b| a[1] <=3D> b[1]}
# sorts only on first value... how can I sort on both.. ?

try sort_by

irb(main):020:0> a=3D[["a", 3, 3], ["c", 1, 5], ["b", 1, 2],["d",3,1]]
=3D> [["a", 3, 3], ["c", 1, 5], ["b", 1, 2], ["d", 3, 1]]
irb(main):021:0> a.sort_by {|x| [x[1],x[2]]}
=3D> [["b", 1, 2], ["c", 1, 5], ["d", 3, 1], ["a", 3, 3]]

Thanks for sort_by.
I didn't know that.

Harry


--=20
http://www.kakueki.com/ruby/list.html
A Look into Japanese Ruby List in English
 
C

Charles Lowe

Harry said:
Thanks for sort_by.
I didn't know that.

Harry

Just using sort won't get the results into nested arrays based on the
groupings. For this, you need group_by:

anArray.group_by { |a| a[1..2] }.sort.transpose[1]
 
R

Raf Coremans

2007/5/3 said:
given an array

anArray = [["a", 1, 1], ["b", 1, 2], ["c", 1, 5], ["z", 1, 1], ["e", 1,
5], ["f", 1, 6], ["g", 1, 1], ["h", 1, 3], ["i", 1, 1], ["j", 1, 2],
["k", 1, 1], ["y", 1, 6], ["m", 1, 1], ["u", 1, 2], ["v", 1, 1], ["p",
1, 4], ["q", 1, 5], ["r", 1, 1], ["n", 1, 1], ["t", 2, 3], ["s", 2, 2],
["o", 2, 1], ["w", 2, 1], ["x", 2, 1], ["l", 2, 1], ["d", 2, 1]]

I would like to get it sliced in groups of element having the same 2nd
and 3rd values

sliced_array = [
[ ["a", 1, 1],["g", 1, 1], ["i", 1, 1], ["k", 1, 1], ["m", 1, 1], ["n",
1, 1],["r", 1, 1],["v", 1, 1],["z", 1, 1] ],
[ ["b", 1, 2],["j", 1, 2], ["u", 1, 2] ],
[ ["c", 1, 5],["e", 1, 5],["q", 1, 5] ],
[ ["d", 2, 1],["l", 2, 1], ["l", 2, 1], ["o", 2, 1],["w", 2, 1],["x", 2, 1] ],
[ ["f", 1, 6],["y", 1, 6] ],
[ ["h", 1, 3] ],
[ ["p", 1, 4] ],
[ ["s", 2, 2] ],
[ ["t", 2, 3] ]
]

Applying a trick I learned today:

anArray.inject( Hash.new{ |hash, key| hash[key] =[] } ){ |hash,
subarray| hash[subarray[1, 2]] << subarray; hash }.values

Or if you need a sorted result:

anArray.inject( Hash.new{ |hash, key| hash[key] =[] } ){ |hash,
subarray| hash[subarray[1, 2]] << subarray; hash }.values.sort_by{
|subarray| subarray[0][1,2] }


Best regards,
Raf
 
J

Josselin

2007/5/3 said:
given an array

anArray = [["a", 1, 1], ["b", 1, 2], ["c", 1, 5], ["z", 1, 1], ["e", 1,
5], ["f", 1, 6], ["g", 1, 1], ["h", 1, 3], ["i", 1, 1], ["j", 1, 2],
["k", 1, 1], ["y", 1, 6], ["m", 1, 1], ["u", 1, 2], ["v", 1, 1], ["p",
1, 4], ["q", 1, 5], ["r", 1, 1], ["n", 1, 1], ["t", 2, 3], ["s", 2, 2],
["o", 2, 1], ["w", 2, 1], ["x", 2, 1], ["l", 2, 1], ["d", 2, 1]]

I would like to get it sliced in groups of element having the same 2nd
and 3rd values

sliced_array = [
[ ["a", 1, 1],["g", 1, 1], ["i", 1, 1], ["k", 1, 1], ["m", 1, 1], ["n",
1, 1],["r", 1, 1],["v", 1, 1],["z", 1, 1] ],
[ ["b", 1, 2],["j", 1, 2], ["u", 1, 2] ],
[ ["c", 1, 5],["e", 1, 5],["q", 1, 5] ],
[ ["d", 2, 1],["l", 2, 1], ["l", 2, 1], ["o", 2, 1],["w", 2, 1],["x", 2, 1] ],
[ ["f", 1, 6],["y", 1, 6] ],
[ ["h", 1, 3] ],
[ ["p", 1, 4] ],
[ ["s", 2, 2] ],
[ ["t", 2, 3] ]
]

Applying a trick I learned today:

anArray.inject( Hash.new{ |hash, key| hash[key] =[] } ){ |hash,
subarray| hash[subarray[1, 2]] << subarray; hash }.values

Or if you need a sorted result:

anArray.inject( Hash.new{ |hash, key| hash[key] =[] } ){ |hash,
subarray| hash[subarray[1, 2]] << subarray; hash }.values.sort_by{
|subarray| subarray[0][1,2] }


Best regards,
Raf

good to know , what about the partition_by , it seems simple ?

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'
sArray = anArray.sort_by {|item| [item[1], item[2] ] }

sArray.partition_by {|ary| ary[1..2]}.to_enum:)each_value).to_a=>
[[["j", 1, 2], ["u", 1, 2], ["b", 1, 2]], [["l", 2, 1], ["x", 2, 1],
["o", 2, 1], ["w", 2, 1], ["d", 2, 1]], [["a", 1, 1], ["z", 1, 1],
["v", 1, 1], ["r", 1, 1], ["i", 1, 1], ["m", 1, 1], ["g", 1, 1], ["k",
1, 1], ["n", 1, 1]], [["f", 1, 6], ["y", 1, 6]], [["t", 2, 3]], [["c",
1, 5], ["e", 1, 5], ["q", 1, 5]], [["s", 2, 2]], [["p", 1, 4]], [["h",
1, 3]]]

and that's it.....
 
J

Josselin

given an array

anArray = [["a", 1, 1], ["b", 1, 2], ["c", 1, 5], ["z", 1, 1], ["e", 1,
5], ["f", 1, 6], ["g", 1, 1], ["h", 1, 3], ["i", 1, 1], ["j", 1, 2],
["k", 1, 1], ["y", 1, 6], ["m", 1, 1], ["u", 1, 2], ["v", 1, 1], ["p",
1, 4], ["q", 1, 5], ["r", 1, 1], ["n", 1, 1], ["t", 2, 3], ["s", 2, 2],
["o", 2, 1], ["w", 2, 1], ["x", 2, 1], ["l", 2, 1], ["d", 2, 1]]

I would like to get it sliced in groups of element having the same 2nd
and 3rd values

sliced_array = [
[ ["a", 1, 1],["g", 1, 1], ["i", 1, 1], ["k", 1, 1], ["m", 1, 1], ["n",
1, 1],["r", 1, 1],["v", 1, 1],["z", 1, 1] ],
[ ["b", 1, 2],["j", 1, 2], ["u", 1, 2] ],
[ ["c", 1, 5],["e", 1, 5],["q", 1, 5] ],
[ ["d", 2, 1],["l", 2, 1], ["l", 2, 1], ["o", 2, 1],["w", 2, 1],["x", 2, 1] ],
[ ["f", 1, 6],["y", 1, 6] ],
[ ["h", 1, 3] ],
[ ["p", 1, 4] ],
[ ["s", 2, 2] ],
[ ["t", 2, 3] ]
]

I believe teh first step is to sort anArray.... then slicing similar
groups, but writing
anArray.sort {|a,b| a[1] <=> b[1]}
sorts only on first value... how can I sort on both.. ?

thansk

joss

a lot of tricks .. good ruby day !
 
R

Raf Coremans

2007/5/3 said:
2007/5/3 said:
given an array

anArray = [["a", 1, 1], ["b", 1, 2], ["c", 1, 5], ["z", 1, 1], ["e", 1,
5], ["f", 1, 6], ["g", 1, 1], ["h", 1, 3], ["i", 1, 1], ["j", 1, 2],
["k", 1, 1], ["y", 1, 6], ["m", 1, 1], ["u", 1, 2], ["v", 1, 1], ["p",
1, 4], ["q", 1, 5], ["r", 1, 1], ["n", 1, 1], ["t", 2, 3], ["s", 2, 2],
["o", 2, 1], ["w", 2, 1], ["x", 2, 1], ["l", 2, 1], ["d", 2, 1]]

I would like to get it sliced in groups of element having the same 2nd
and 3rd values

sliced_array = [
[ ["a", 1, 1],["g", 1, 1], ["i", 1, 1], ["k", 1, 1], ["m", 1, 1], ["n",
1, 1],["r", 1, 1],["v", 1, 1],["z", 1, 1] ],
[ ["b", 1, 2],["j", 1, 2], ["u", 1, 2] ],
[ ["c", 1, 5],["e", 1, 5],["q", 1, 5] ],
[ ["d", 2, 1],["l", 2, 1], ["l", 2, 1], ["o", 2, 1],["w", 2, 1],["x", 2, 1] ],
[ ["f", 1, 6],["y", 1, 6] ],
[ ["h", 1, 3] ],
[ ["p", 1, 4] ],
[ ["s", 2, 2] ],
[ ["t", 2, 3] ]
]

Applying a trick I learned today:

anArray.inject( Hash.new{ |hash, key| hash[key] =[] } ){ |hash,
subarray| hash[subarray[1, 2]] << subarray; hash }.values

Or if you need a sorted result:

anArray.inject( Hash.new{ |hash, key| hash[key] =[] } ){ |hash,
subarray| hash[subarray[1, 2]] << subarray; hash }.values.sort_by{
|subarray| subarray[0][1,2] }


Best regards,
Raf

good to know , what about the partition_by , it seems simple ?

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'
sArray = anArray.sort_by {|item| [item[1], item[2] ] }

sArray.partition_by {|ary| ary[1..2]}.to_enum:)each_value).to_a=>
[[["j", 1, 2], ["u", 1, 2], ["b", 1, 2]], [["l", 2, 1], ["x", 2, 1],
["o", 2, 1], ["w", 2, 1], ["d", 2, 1]], [["a", 1, 1], ["z", 1, 1],
["v", 1, 1], ["r", 1, 1], ["i", 1, 1], ["m", 1, 1], ["g", 1, 1], ["k",
1, 1], ["n", 1, 1]], [["f", 1, 6], ["y", 1, 6]], [["t", 2, 3]], [["c",
1, 5], ["e", 1, 5], ["q", 1, 5]], [["s", 2, 2]], [["p", 1, 4]], [["h",
1, 3]]]

and that's it.....

Yes. I think it could be improved though:

module Enumerable
def partition_by
inject( Hash.new{ |h,k| h[k]=[] } ){ |h, e| h[ yield( e)] << e; h }.values
end
end

p anArray.partition_by { |e| e[1, 2] } =>
[[["b", 1, 2], ["j", 1, 2], ["u", 1, 2]], [["o", 2, 1], ["w", 2, 1],
["x", 2, 1], ["l", 2, 1], ["d", 2, 1]], [["a", 1, 1], ["z", 1, 1],
["g", 1, 1], ["i", 1, 1], ["k", 1, 1], ["m", 1, 1], ["v", 1, 1], ["r",
1, 1], ["n", 1, 1]], [["f", 1, 6], ["y", 1, 6]], [["t", 2, 3]], [["c",
1, 5], ["e", 1, 5], ["q", 1, 5]], [["s", 2, 2]], [["p", 1, 4]], [["h",
1, 3]]]

Or if you want it sorted:
p anArray.sort.partition_by{ |subarray| subarray[1, 2] }.sort_by{ |e|
e[0][1,2] } => [[["a", 1, 1], ["g", 1, 1], ["i", 1, 1], ["k", 1, 1],
["m", 1, 1], ["n", 1, 1], ["r", 1, 1], ["v", 1, 1], ["z", 1, 1]],
[["b", 1, 2], ["j", 1, 2], ["u", 1, 2]], [["h", 1, 3]], [["p", 1, 4]],
[["c", 1, 5], ["e", 1, 5], ["q", 1, 5]], [["f", 1, 6], ["y", 1, 6]],
[["d", 2, 1], ["l", 2, 1], ["o", 2, 1], ["w", 2, 1], ["x", 2, 1]],
[["s", 2, 2]], [["t", 2, 3]]]


Regards,
Raf
 

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,999
Messages
2,570,246
Members
46,839
Latest member
MartinaBur

Latest Threads

Top