array handling advice

C

Chris McMahon

There is probably a simple way to do this, but I'm drawing a blank:

I have an arbitrarily large input array, like

input = ['a','b','c','d','e','f','g']

and three target arrays like

targ_one = []
targ_two = []
targ_three = []

I want to deal out the elements of this array into three target arrays
so they end up like

['a','d','g']
['b','e']
['c','f']

It seems there should be an elegant way to do this, but I haven't hit
on it. Suggestions would be welcome.
 
G

Gordon Thiesfeld

There is probably a simple way to do this, but I'm drawing a blank:

I have an arbitrarily large input array, like

input = ['a','b','c','d','e','f','g']

and three target arrays like

targ_one = []
targ_two = []
targ_three = []

I want to deal out the elements of this array into three target arrays
so they end up like

['a','d','g']
['b','e']
['c','f']

This is the best I could come up with:

require 'enumerator'

input = ['a','b','c','d','e','f','g']
input = *input.enum_slice(3)
targ_one, targ_two, targ_three = input.shift.zip(*input).map{|i| i.compact }

hth

Gordon
 
A

Axel

There is probably a simple way to do this

Like this?:

input = ['a','b','c','d','e','f','g']
targ_one, targ_two, targ_three = input[0,3], input[3,2], input[5,2]

- Axel
 
R

Robert Klemme

There is probably a simple way to do this, but I'm drawing a blank:

I have an arbitrarily large input array, like

input = ['a','b','c','d','e','f','g']

and three target arrays like

targ_one = []
targ_two = []
targ_three = []

I want to deal out the elements of this array into three target arrays
so they end up like

['a','d','g']
['b','e']
['c','f']

This is the best I could come up with:

require 'enumerator'

input = ['a','b','c','d','e','f','g']
input = *input.enum_slice(3)
targ_one, targ_two, targ_three = input.shift.zip(*input).map{|i| i.compact }

Cute! Here's my attempt:

$ irb -r enumerator
irb(main):001:0> a=%w{a b c d e f g h}
=> ["a", "b", "c", "d", "e", "f", "g", "h"]
irb(main):002:0> a.to_enum:)each_with_index).inject([[],[],[]])
{|ar,(x,i)| ar[i%ar.size] << x;ar}
=> [["a", "d", "g"], ["b", "e", "h"], ["c", "f"]]

Kind regards

robert
 
A

Axel

My second attempt:

input = ['a','b','c','d','e','f','g']
targ = { 0 => targ_one=[], 1 => targ_two=[], 2 => targ_three=[] }

input.each_with_index do |elem, idx|
ii = idx.divmod(3)[1]
targ[ii] << elem
end


- Axel
 
W

William James

There is probably a simple way to do this, but I'm drawing a blank:

I have an arbitrarily large input array, like

input = ['a','b','c','d','e','f','g']

and three target arrays like

targ_one = []
targ_two = []
targ_three = []

I want to deal out the elements of this array into three target arrays
so they end up like

['a','d','g']
['b','e']
['c','f']

It seems there should be an elegant way to do this, but I haven't hit
on it. Suggestions would be welcome.

input = ['a','b','c','d','e','f','g']
def seq lo,hi,gap
(0 .. ((hi-lo)/gap)).map{|n| n*gap + lo}
end

output = (0..2).map{|i|
input.values_at( *seq(i,input.size-1,3) ) }
 
E

Erik Veenstra

For better readability, define it in a library. And if it's
defined in a library, well, you might want to write the
implementation in a readable way... :}

gegroet,
Erik V. - http://www.erikveen.dds.nl/

----------------------------------------------------------------

module Enumerable
def group_by_size(size)
res = []

each_with_index do |o, n|
res << [] if n%size == 0

res[-1] << o
end

res
end
end

a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
b = a.group_by_size(3)

p a
p b

----------------------------------------------------------------
 
W

William James

For better readability, define it in a library. And if it's
defined in a library, well, you might want to write the
implementation in a readable way... :}

gegroet,
Erik V. -http://www.erikveen.dds.nl/

----------------------------------------------------------------

module Enumerable
def group_by_size(size)
res = []

each_with_index do |o, n|
res << [] if n%size == 0

res[-1] << o
end

res
end
end

a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
b = a.group_by_size(3)

p a
p b

----------------------------------------------------------------

1. Doesn't enum_slice do this?
2. This isn't what the o.p. wants.
 
S

Simon Kröger

Chris said:
There is probably a simple way to do this, but I'm drawing a blank:

Well, no, not exactly simple.

first, *rest = *input.enum_slice(3)
one, two, three = first.zip(*rest).map{|a| a.compact}

is the most elegant way i came up with - if you can live with a result like

["a", "d", "g"]
["b", "e", nil]
["c", "f", nil]

than you can strip it down to

first, *rest = *input.enum_slice(3)
one, two, three = first.zip(*rest)

which starts to look nice - if on the other hand you have nil values in your
data (and want to keep them) you are pretty screwed with this appoach.

cheers

Simon
 
P

Pena, Botp

From: Felix Windt [mailto:[email protected]]=20
# irb(main):002:0> b =3D [[], [], []]
# =3D> [[], [], []]
# irb(main):003:0> a.inject(0){|bucket, item| b[bucket] <<=20
# item; bucket < 2 ? bucket + 1 : 0}
# =3D> 0
# irb(main):004:0> b
# =3D> [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
#=20
# Though I don't know if that would be considered elegant.

i would consider that as simple and elegant.

btw, in 1.9 there will be group_by and a with_index,
so hopefully,

a.group_by.with_index{|_,i| i%3}.values
=3D>[[1, 4, 7], [2, 5, 8], [3, 6, 9]]

kind regards -botp
 

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,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top