Forum: Ruby Faster way to pick the every other array member?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
damphyr (Guest)
on 2005-11-25 12:51
(Received via mailing list)
we have [1,2,3,4,5,6,7] and want [2,4,6]

Is there a way other than

fields=[1,2,3,4,5,6,7]
fields.collect!{|f|
	f if fields.index(f)%2==1
}.compact!

And by another way I mean something shorter and more beautiful :).
Cheers,
V.-
--
http://www.braveworld.net/riva
christophe.poucet (Guest)
on 2005-11-25 13:03
(Received via mailing list)
Hello

You can try the following:

fields = ["a", "b", "c", "d", "e", "f"]
new_fields =[]
fields.each_index {|i| new_fields << fields[i] if i %2 == 0}

Cheers,
Christophe
gene.tani (Guest)
on 2005-11-25 13:56
(Received via mailing list)
Christophe Poucet wrote:
> Hello
>
> You can try the following:
>
> fields = ["a", "b", "c", "d", "e", "f"]
> new_fields =[]
> fields.each_index {|i| new_fields << fields[i] if i %2 == 0}
>
> Cheers,
> Christophe

http://redhanded.hobix.com/inspect/hopscotchingArr...
SimonKroeger (Guest)
on 2005-11-25 14:04
(Received via mailing list)
Damphyr wrote:
> Cheers,
> V.-

what about:

f = true
fields = fields.select{f=!f}

cheers

Simon
christophe.poucet (Guest)
on 2005-11-25 14:45
(Received via mailing list)
To be honest, I think that the hopscotching technique as well as:

> f = true
> fields = fields.select{f=!f}

are rather dirty hacks.  They are short but they do not clearly convey
the meaning of the program.
gene.tani (Guest)
on 2005-11-25 15:13
(Received via mailing list)
Christophe Poucet wrote:
> To be honest, I think that the hopscotching technique as well as:
>
> > f = true
> > fields = fields.select{f=!f}
>
> are rather dirty hacks.  They are short but they do not clearly convey
> the meaning of the program.

There's probably dozens of ways to do it:

require 'enumerator'
(1..10).each_slice(3) {|slc| p slc[0]}
dblack (Guest)
on 2005-11-25 15:25
(Received via mailing list)
Hi --

On Fri, 25 Nov 2005, Damphyr wrote:

> we have [1,2,3,4,5,6,7] and want [2,4,6]
>
> Is there a way other than
>
> fields=[1,2,3,4,5,6,7]
> fields.collect!{|f|
> 	f if fields.index(f)%2==1
> }.compact!
>
> And by another way I mean something shorter and more beautiful :).

Here's one possibility:

irb(main):016:0> a = [1,2,3,4,5,6,7]
=> [1, 2, 3, 4, 5, 6, 7]
irb(main):017:0> res = []
=> []
irb(main):018:0> (1...a.size).step(2) {|n| res << a[n] }
=> 1...7
irb(main):019:0> res
=> [2, 4, 6]


David
dooby (Guest)
on 2005-11-25 16:26
(Received via mailing list)
Damphyr wrote:
> we have [1,2,3,4,5,6,7] and want [2,4,6]
>


( A more general version of Simon's:
     f=true; p a.select{f=!f}    ):

#--------
  ix=-1; p a.select{ (ix+=1)%2==1 }   #-> [2, 4, 6]
#--------

(Not pretty ... not my fault)


I would prefer not having to maintain the index
in these situations.  Something like this would
suit many similar needs:

<pseudo>
  p a.select{ _i_%2==1 }
</>

- where _i_ (or whatever) is the index that Ruby
is using internally.


daz
gregory.t.brown (Guest)
on 2005-11-25 17:59
(Received via mailing list)
On 11/25/05, Damphyr <removed_email_address@domain.invalid> wrote:

> And by another way I mean something shorter and more beautiful :).

class Array

  def skipper(interval=2,position=0)
      (position...length).select { |i| i % interval == 0 }.map { |i|
self[i] }
  end

end
matti.georgi (Guest)
on 2005-11-25 21:13
(Received via mailing list)
Another one:

module Enumerable
  def select_with_index
    index = 0
    select { |item|
      res = yield item, index
      index += 1
      res
    }
  end
end

[1,2,3,4,5,6,7].select_with_index {|n, i| i % 2 == 1 }

I know this is basically the same, but you can see clearly what is
happening.
pit (Guest)
on 2005-11-25 23:10
(Received via mailing list)
Damphyr schrieb:
> we have [1,2,3,4,5,6,7] and want [2,4,6]
>
> Is there a way other than
>
> fields=[1,2,3,4,5,6,7]
> fields.collect!{|f|
>     f if fields.index(f)%2==1
> }.compact!
>
> And by another way I mean something shorter and more beautiful :).

   fields.values_at(*(0...fields.size).select{|i|i%2==1})

Regards,
Pit
w_a_x_man (Guest)
on 2005-11-26 01:47
(Received via mailing list)
Damphyr wrote:
> we have [1,2,3,4,5,6,7] and want [2,4,6]
>
> Is there a way other than
>
> fields=[1,2,3,4,5,6,7]
> fields.collect!{|f|
> 	f if fields.index(f)%2==1
> }.compact!

fields.values_at( 1,3,5 )

or

fields.values_at( *Array.new(fields.size/2){|i|i*2+1} )
jzakiya (Guest)
on 2005-11-26 02:07
(Received via mailing list)
res=[]; 1.step(a.size-1,2) {|n| res << a[n] }
jeff.darklight (Guest)
on 2005-11-26 02:15
(Received via mailing list)
I'm kind of surprised that you don't get an array of values back if you
call
Range#step(x) without a block.

That would make things much easier ...

a.values_at( (2..6).step(2) )

... at least, that is what would make sense to me ... anybody else?

j.


On 11/25/05, removed_email_address@domain.invalid 
<removed_email_address@domain.invalid> wrote:
>
> res=[]; 1.step(a.size-1,2) {|n| res << a[n] }
>
>
>


--
"Remember. Understand. Believe. Yield! -> http://ruby-lang.org"

Jeff W.
dblack (Guest)
on 2005-11-26 02:24
(Received via mailing list)
Hi --

On Sat, 26 Nov 2005, Jeff W. wrote:

> I'm kind of surprised that you don't get an array of values back if you call
> Range#step(x) without a block.
>
> That would make things much easier ...
>
> a.values_at( (2..6).step(2) )
>
> ... at least, that is what would make sense to me ... anybody else?

I can see your reasoning though I tend to come down on the side of not
liking iterators to create accumulator arrays unless you ask them to.
It's kind of the same thing as the (much discussed) question of
whether a.zip(b) with a block should also return the zipped array (as
opposed to having the block be a way to avoid creating the whole
array).


David
jzakiya (Guest)
on 2005-11-26 04:48
(Received via mailing list)
res=[]; 1.step(a.size-1,2) {|n| res << a[n] }
mfp (Guest)
on 2005-11-26 04:48
(Received via mailing list)
On Sat, Nov 26, 2005 at 09:13:38AM +0900, Jeff W. wrote:
> I'm kind of surprised that you don't get an array of values back if you call
> Range#step(x) without a block.
>
> That would make things much easier ...
>
> a.values_at( (2..6).step(2) )
>
> ... at least, that is what would make sense to me ... anybody else?

a = (0..20).to_a
a.values_at( *(2..6).step(2) ) # => [2, 4, 6]
RUBY_VERSION                   # => "1.9.0"
jeff.darklight (Guest)
on 2005-11-26 14:33
(Received via mailing list)
Other than having to do the * that's very cool.

It should be smart enought to figure out input param types ....

or maybe add to the syntax for ranges ? ( 2..6 by 2 ) could be cool too

Anyways, thanks for the note about 1.9

j.


On 11/25/05, Mauricio Fernández <removed_email_address@domain.invalid > wrote:
> > ... at least, that is what would make sense to me ... anybody else?
>
> a = (0..20).to_a
> a.values_at( *(2..6).step(2) ) # => [2, 4, 6]
> RUBY_VERSION                   # => "1.9.0"
>
> --
> Mauricio F.
>
>


--
"Remember. Understand. Believe. Yield! -> http://ruby-lang.org "

Jeff W.
This topic is locked and can not be replied to.