Reputation: 311
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
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
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
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