Odd/Even numbered index items of a list

It’s just for understanding the concept. We know more built-in methods
of Array Class. If I need to separate the item(s) of a list by even
numbered index and odd numbered index.

arr=[12,11,‘a’,:true,300,-22,{},[],‘n-1’,‘n’]

code want to produces,

arr_odd=[11,:true,-22,[],‘n’]
arr_even=[12,‘a’,300,{},‘n-1’]

arr_odd=[];
arr_even=[];
arr.each {|x| a.index(x).even? ? arr_even << x : arr_odd << x}

Hi,

2014-03-05 15:34 GMT+09:00 Selvag R. [email protected]:

You can do something like this:
arr_even,arr_odd=arr.each_with_index.partition{|v|v[1].even?}.map{|v|v.map{|v|v[0]}}

Regards,
Park H.

Hi,

2014-03-05 17:31 GMT+09:00 Robert K. [email protected]:

irb(main):023:0> arr.each_with_object([[],[]]).each_with_index {|(x,
(even, odd)), i| (i.odd? ? odd : even) << x}
=> [[12, “a”, 300, {}, “n-1”], [11, :true, -22, [], “n”]]

In all cases just assign via multiple assignment:

arr_even, arr_odd = expr…

I found a bit more compact and efficient way

irb(main):037:0> arr.partition.with_index{|x,i|i.odd?}
=> [[11, :true, -22, [], “n”], [12, “a”, 300, {}, “n-1”]]

Regards,
Park H.

On Wed, Mar 5, 2014 at 8:42 AM, Heesob P. [email protected] wrote:

arr_even,arr_odd=arr.each_with_index.partition{|v|v[1].even?}.map{|v|v.map{|v|v[0]}}

We can be a bit more efficient memory wise by replacing #map with
#each and #map!

irb(main):008:0> arr.each_with_index.partition {|x,i| i.odd?}.each
{|a| a.map!(&:first)}
=> [[11, :true, -22, [], “n”], [12, “a”, 300, {}, “n-1”]]

Here’s another approach

irb(main):014:0> arr.each_slice(2).each_with_object([[],[]])
{|(a,b),(even,odd)| even << a; odd << b}
=> [[12, “a”, 300, {}, “n-1”], [11, :true, -22, [], “n”]]

irb(main):016:0> arr.each_with_index.each_with_object([[],[]])
{|(x,i),(even,odd)| (i.odd? ? odd : even) << x}
=> [[12, “a”, 300, {}, “n-1”], [11, :true, -22, [], “n”]]

irb(main):023:0> arr.each_with_object([[],[]]).each_with_index {|(x,
(even, odd)), i| (i.odd? ? odd : even) << x}
=> [[12, “a”, 300, {}, “n-1”], [11, :true, -22, [], “n”]]

In all cases just assign via multiple assignment:

arr_even, arr_odd = expr…

Kind regards

robert

On Mar 5, 2014, at 0:57, Heesob P. [email protected] wrote:

I found a bit more compact and efficient way

irb(main):037:0> arr.partition.with_index{|x,i|i.odd?}
=> [[11, :true, -22, [], “n”], [12, “a”, 300, {}, “n-1”]]

Doing an #odd? test on each iteration for such a task is wasteful. You
know ahead of time if it is even or odd.

even, odd = arr.each_slice(2).to_a.transpose

Ryan D. wrote in post #1138871:

even, odd = arr.each_slice(2).to_a.transpose

This is nice, but you’d have to be sure that there’s an even number of
values.
arr << nil if arr.length.odd?

On Mar 7, 2014 6:47 AM, “Regis d'Aubarede” [email protected]
wrote:

h=Hash[*array]
even,odd=h.keys,h.values

Only if there are no duplicate evens.

On Wed, Mar 5, 2014 at 1:57 PM, Heesob P. [email protected] wrote:

irb(main):016:0> arr.each_with_index.each_with_object([[],[]])

I found a bit more compact and efficient way

irb(main):037:0> arr.partition.with_index{|x,i|i.odd?}
=> [[11, :true, -22, [], “n”], [12, “a”, 300, {}, “n-1”]]

Indeed Park’s iteration takes the shortest time.
Partitions are way faster than .each loops.

[87] pry(main)> a.size
=> 10001
[88] pry(main)> Benchmark.measure { a.partition.with_index{|x,i| i.odd?
?
odd << x : even << x} }
=> #<Benchmark::Tms:0x00000003e5a3f0
@cstime=0.0,
@cutime=0.0,
@label=“”,
@real=0.004411993,
@stime=0.0,
@total=0.0,
@utime=0.0>

Ryan D. wrote in post #1138871:

On Mar 5, 2014, at 0:57, Heesob P. [email protected] wrote:

I found a bit more compact and efficient way

irb(main):037:0> arr.partition.with_index{|x,i|i.odd?}
=> [[11, :true, -22, [], “n”], [12, “a”, 300, {}, “n-1”]]

Doing an #odd? test on each iteration for such a task is wasteful. You
know ahead of time if it is even or odd.

even, odd = arr.each_slice(2).to_a.transpose

Thanks! I got smart way from more.

On Sat, Mar 8, 2014 at 1:16 AM, Micky [email protected] wrote:

Indeed Park’s iteration takes the shortest time.

Partitions are way faster than .each loops.

If you claim that then posting only the timing of one approach won’t
prove
much.

[87] pry(main)> a.size
=> 10001
[88] pry(main)> Benchmark.measure { a.partition.with_index{|x,i| i.odd? ?
odd << x : even << x} }
=> #<Benchmark::Tms:0x00000003e5a3f0

That does not make sense: first, you’re not using #partition at all.
Without a block as criterion this just creates an Enumerator - much the
same as #each does without a block.

irb(main):017:0> a = 10.times.map {|x| “x-#{x}”}
=> [“x-0”, “x-1”, “x-2”, “x-3”, “x-4”, “x-5”, “x-6”, “x-7”, “x-8”,
“x-9”]
irb(main):018:0> x = a.partition
=> #<Enumerator: [“x-0”, “x-1”, “x-2”, “x-3”, “x-4”, “x-5”, “x-6”,
“x-7”,
“x-8”, “x-9”]:partition>
irb(main):019:0> x.class
=> Enumerator
irb(main):020:0> x.to_a
=> [“x-0”, “x-1”, “x-2”, “x-3”, “x-4”, “x-5”, “x-6”, “x-7”, “x-8”,
“x-9”]

Then, you’re adding elements to some “odd” or “even” that you do not
show
here. If you do that then you don’t need partition at all. Rather use
#each_with_index and do the distribution:

irb(main):021:0> odd = []
=> []
irb(main):022:0> even = []
=> []
irb(main):023:0> a.each_with_index {|x,i| (i.odd? ? odd : even) << x}
=> [“x-0”, “x-1”, “x-2”, “x-3”, “x-4”, “x-5”, “x-6”, “x-7”, “x-8”,
“x-9”]
irb(main):024:0> odd
=> [“x-1”, “x-3”, “x-5”, “x-7”, “x-9”]
irb(main):025:0> even
=> [“x-0”, “x-2”, “x-4”, “x-6”, “x-8”]

If you want to use #partition in a reasonable way you need to do
something
like this:

irb(main):026:0> a.each_with_index.partition {|x,i| i.odd?}.each {|x|
x.map!(&:first)}
=> [[“x-1”, “x-3”, “x-5”, “x-7”, “x-9”], [“x-0”, “x-2”, “x-4”, “x-6”,
“x-8”]]

Here’s another funny approach:

irb(main):030:0> odd, even = [], []
=> [[], []]
irb(main):031:0> a1, a2 = even, odd
=> [[], []]
irb(main):032:0> a.each {|x| a1 << x; a1, a2 = a2, a1}
=> [“x-0”, “x-1”, “x-2”, “x-3”, “x-4”, “x-5”, “x-6”, “x-7”, “x-8”,
“x-9”]
irb(main):033:0> even
=> [“x-0”, “x-2”, “x-4”, “x-6”, “x-8”]
irb(main):034:0> odd
=> [“x-1”, “x-3”, “x-5”, “x-7”, “x-9”]

Kind regards

robert