user3145336
user3145336

Reputation: 311

How do I output the index of elements in an array that are also in another?

I have two arrays:

A = ["a","s","p","e","n"]
V = ["a","e","i","o","u"]

I want to output an array that shows the index of every element in array A that is also an element anywhere in V.

In other words:

some_function(A, V) == [0,3]

This is because A[0]="a" and A[3]="e" matches the elements "a" and "e" in array V. How do I do that?

Upvotes: 1

Views: 1277

Answers (3)

Cary Swoveland
Cary Swoveland

Reputation: 110665

As @Arup has answered your question, I thought I might elaborate a bit. Arup suggested you do this:

A.each_index.select{|i| V.include? A[i]}

where

A = ["a","s","p","e","n"]
V = ["a","e","i","o","u"]

Firstly, what is A.each_index? Try it in IRB:

e = A.each_index # =>  #<Enumerator: ["a", "s", "p", "e", "n"]:each_index>
e.class          # => Enumerator
e.to_a           # => [0, 1, 2, 3, 4]

So the enumerator e is the receiver of the method Enumerable#select, Enumerable being a mix-in module that is included by several Ruby classes, including Enumerator. Want to check that?

e.respond_to?(:select) # => true
e.respond_to?(:map)    # => true
e.respond_to?(:reduce) # => true

Next, note that A.each_index does not depend on the contents of A, just its size, so we could replace that with any enumerator that iterates from 0 to A.size - 1, such as:

m = A.size
m.times.select{|i| V.include? A[i]}         # => [0, 3]
0.upto(m-1).select{|i| V.include? A[i]}     # => [0, 3]

We can confirm these are Enumerator objects:

m.times.class      # => Enumerator
0.upto(m-1).class  # => Enumerator

The other main classes that include Enumerable are Array, Hash, Set, Range and IO (but, since Ruby 1.9, not String), so we could also do this:

Array(0...m).select{|i| V.include? A[i]}    # => [0, 3]
(0...m).select{|i| V.include? A[i]}         # => [0, 3]
require 'set'
Set.new(0..m-1).select{|i| V.include? A[i]} # => [0, 3]

Note that, regardless of the receiver's class, select returns an array. Most (but not all) Enumerable methods that return a collection, return an array, regardless of the receiver's class.

Upvotes: 1

Javid Jamae
Javid Jamae

Reputation: 8999

If V is a Set of data (order doesn't matter, no duplicates), and it is large, then you might get a performance benefit by converting it to a Set so that the include? runs faster since Set is built on a hash and gets O(1) retrieval time:

require 'set'
A = ["a","s","p","e","n"]
V = Set.new ["a","e","i","o","u"]
A.each_index.select{|i| V.include? A[i]} # => [0, 3]

Upvotes: 1

Arup Rakshit
Arup Rakshit

Reputation: 118261

Here is how I would do:

A = ["a","s","p","e","n"]
V = ["a","e","i","o","u"]
A.each_index.select{|i| V.include? A[i]} # => [0, 3]

Upvotes: 1

Related Questions