Arbitrary indexes

There has to be an easier way to do this.

If I have v=(1…99).to_a and I want to index the 20th to 30th elements,
this is simply v[20,10]. But if I have a list of indexes i=[9, 11, 35,
47, 48, 55, 58, 63, 92, 96] that I want, I can’t seem to find a simpler
way than i.map{|x|v[x]} which seem like an aweful lot of syntax just for
what is essentially “v[i]”. Is there an easier way to do this?

-jason

(If your answer is “in Ruby it is easy to change the way basic primitive
operate yourself and hose everybody else in the project”, then please
keep it to yourself… that answer is getting a little tiresome.)

Jason N. wrote:

There has to be an easier way to do this.

If I have v=(1…99).to_a and I want to index the 20th to 30th elements,
this is simply v[20,10]. But if I have a list of indexes i=[9, 11, 35,
47, 48, 55, 58, 63, 92, 96] that I want, I can’t seem to find a simpler
way than i.map{|x|v[x]} which seem like an aweful lot of syntax just for
what is essentially “v[i]”. Is there an easier way to do this?

array.values_at *i

-jason

(If your answer is “in Ruby it is easy to change the way basic primitive
operate yourself and hose everybody else in the project”, then please
keep it to yourself… that answer is getting a little tiresome.)

My answer is to

A) look over the documentation (ri Array, ri Array#values_at)

B) --And I mean this in the kindest way–stop thinking about how
things should be comparing to other languages and just go with the flow.

On 9/12/06, Jason N. [email protected] wrote:

There has to be an easier way to do this.

If I have v=(1…99).to_a and I want to index the 20th to 30th elements, this is simply v[20,10]. But if I have a list of indexes i=[9, 11, 35, 47, 48, 55, 58, 63, 92, 96] that I want, I can’t seem to find a simpler way than i.map{|x|v[x]} which seem like an aweful lot of syntax just for what is essentially “v[i]”. Is there an easier way to do this?

v.values_at(9, 11, 35, 47, 48, 55, 58, 63, 92, 96)
=> [10, 12, 36, 48, 49, 56, 59, 64, 93, 97]

-austin

On Sep 12, 2006, at 12:18 PM, Austin Z. wrote:

v.values_at(9, 11, 35, 47, 48, 55, 58, 63, 92, 96)
=> [10, 12, 36, 48, 49, 56, 59, 64, 93, 97]

Another nice thing about values_at is that it understands ranges:

a = Array.new(10) { |x| x*2 } #=> [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

b = a.values_at(1,3,5…7) #=> [2, 6, 10, 12, 14]

Gary W.

If I have v=(1…99).to_a and I want to index the 20th to 30th elements,
this is simply v[20,10]. But if I have a list of indexes i=[9, 11, 35, 47,
48, 55, 58, 63, 92, 96] that I want, I can’t seem to find a simpler way
than i.map{|x|v[x]} which seem like an aweful lot of syntax just for what
is essentially “v[i]”. Is there an easier way to do this?

v.values_at(*i)

(If your answer is “in Ruby it is easy to change the way basic primitive
operate yourself and hose everybody else in the project”, then please keep
it to yourself… that answer is getting a little tiresome.)

So tempting not to answer at all… or to tell you to RTFM…

Rick DeNatale wrote:

irb(main):005:0> (0…10).to_a.values_at([2, 3, 4, 5])
TypeError: can’t convert Array into Integer
from (irb):5:in `values_at’
from (irb):5
from :0

This seems a little inconsistent, it would seem better if it handled
any arguments which were enumerables containing integers.

I see your point. But you can just use an asterisk
to expand it.

Hal

On 9/13/06, [email protected] [email protected] wrote:

Another nice thing about values_at is that it understands ranges:

a = Array.new(10) { |x| x*2 } #=> [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

b = a.values_at(1,3,5…7) #=> [2, 6, 10, 12, 14]

But not an array?!

irb(main):005:0> (0…10).to_a.values_at([2, 3, 4, 5])
TypeError: can’t convert Array into Integer
from (irb):5:in `values_at’
from (irb):5
from :0

This seems a little inconsistent, it would seem better if it handled
any arguments which were enumerables containing integers.


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

What would seem most natural (and best) would be:

a[1,3,5,6,7] or more generally a[list] (a[*list] seems unnecessarily
complex and would be inconsistent with a[x…y] that is allowed).

Is there a good reason this shouldn’t be allowed? It would certainly
simplify and shorten much of my code.

-j

Eero S. wrote:

[1, 2, 3, 4, 5][1, 3] # => [2, 3, 4]

Oh course. That’s (now) blindingly obvious. I don’t think there is much
I can do to prevent all the value_at calls. I can’t really lay out my
arrays differently to get better continuity, and I seem to be using
value_at almost every line where there is a decent amount of
computation. Overall, arbitrary indexing seems far more useful than
range based indexing using the [start,len] notation. After all, there is
already start…/…stop notation. Too bad I guess.

-j

Jason N. wrote:

What would seem most natural (and best) would be:

a[1,3,5,6,7] or more generally a[list] (a[*list] seems unnecessarily
complex and would be inconsistent with a[x…y] that is allowed).

Is there a good reason this shouldn’t be allowed? It would certainly
simplify and shorten much of my code.

It conflicts with the current implementation

[1, 2, 3, 4, 5][1, 3] # => [2, 3, 4]

On a tangent, if you find yourself doing a lot
of #values_at, you may want to consider possibly
changing your datastructure.

-j

P.S., that is still no reason Enumerable[list] should not be allowed
that I can see.

a=[0,11,22,33,44,55]
b=[1,3]

where a[b] would return [11,33]

even if this would look a little funny in its constant form:

a[[1,3]]

-j