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.
irb(main):001:0> a = [1,2,3,4,5,6,7,8,9]
=> [1, 2, 3, 4, 5, 6, 7, 8, 9]
irb(main):002:0> b = [ , , ]
=> [ , , ]
irb(main):003:0> a.inject(0){|bucket, item| b[bucket] << item; bucket < 2 ?
bucket + 1 : 0}
=> 0
irb(main):004:0> b
=> [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
irb(main):005:0>
Though I don't know if that would be considered elegant.
HTH,
FElix
···
-----Original Message-----
From: Chris McMahon [mailto:christopher.mcmahon@gmail.com]
Sent: Friday, September 07, 2007 10:40 AM
To: ruby-talk ML
Subject: array handling advice
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.
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
···
On 9/7/07, Chris McMahon <christopher.mcmahon@gmail.com> wrote:
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']
Axel
(Axel)
7 September 2007 18:55
4
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
W_James
(W. James)
7 September 2007 20:20
5
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) ) }
···
On Sep 7, 12:38 pm, Chris McMahon <christopher.mcma...@gmail.com> wrote:
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.
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
----------------------------------------------------------------
Chris McMahon schrieb:
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
Robert_K1
(Robert K.)
7 September 2007 19:00
8
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
···
On 07.09.2007 20:15, Gordon Thiesfeld wrote:
On 9/7/07, Chris McMahon <christopher.mcmahon@gmail.com> wrote:
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 }
W_James
(W. James)
7 September 2007 21:05
9
1. Doesn't enum_slice do this?
2. This isn't what the o.p. wants.
···
On Sep 7, 3:32 pm, Erik Veenstra <erikv...@gmail.com> wrote:
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
----------------------------------------------------------------
# irb(main):002:0> b = [[], [], []]
# => [[], [], []]
# irb(main):003:0> a.inject(0){|bucket, item| b[bucket] <<
# item; bucket < 2 ? bucket + 1 : 0}
# => 0
# irb(main):004:0> b
# => [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
···
From: Felix Windt [mailto:fwmailinglists@gmail.com ]
#
# 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
=>[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
kind regards -botp
Axel
(Axel)
7 September 2007 19:50
11
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