0
array3 =['Maths', 'Programming', 'Physics'], ['Maths', 'Intro to comp. science', 'Programming'], ['English', 'Intro to comp. science', 'Physics']
course = 'Programming'    
index = []
array3.find_index do |i|
  if array3.include?(course) == true
  index << i
  end
end

i created an array (array3) that contains the respective elements and i want to add the elements of array3 which hold the condition true but after executing the code i get a blank array like "[[], [], []]" how can i fix this issue?

8
  • 1
    Tip: In Ruby x == true is almost always better written as x. Commented Dec 27, 2022 at 14:16
  • Hint: This is really just index. The find_index name is misleading. Additionally the argument to the index block is not i as in index, but the value. It returns the index. Commented Dec 27, 2022 at 14:18
  • Do you want to add the elements, or the index of the elements? Commented Dec 27, 2022 at 14:19
  • 1
    Defining array3 like that is problematic for two reasons. 1. It should be array3 = [ [ ... ], ... ] where it's clear that's a 3 part array. 2. The name is terrible. Call it courses or something meaningful. Commented Dec 27, 2022 at 14:20
  • 1
    Or as it stands maybe course_lists is a fitting name. This also helps the reader to understand that they're working with a nested arrays. Commented Dec 27, 2022 at 14:23

2 Answers 2

2

find_index does not iterate over indices. It iterates over values and returns the first index of the value that matches. It sounds like you want to iterate over every element, making note of all of the indices that match some condition.

To that end, you can use each_with_index.

index = []
array3.each_with_index do |courses, i|
  if courses.include?(course) == true
  index << i
  end
end

or you can use each_index and filter the results.

index = array3.each_index.select { |index| array3[index].include? course }

or, filtering with each_with_index,

index = array3.each_with_index
        .select { |list, _| list.include? course }
        .map(&:last)

on Ruby 2.7 or newer, you can shorten this with filter_map.

index = array3.each_with_index
              .filter_map { |obj, index| index if obj.include? course }
Sign up to request clarification or add additional context in comments.

7 Comments

The second form is more typical Ruby and it works great.
Though I think the second form is missing the right arguments. It should be each_with_index and then |list, index| as that'd make it easier to do tests: list.include?(course).
@tadman I don't either, to be honest. And I'm surprised Ruby doesn't have a find_all_indices method built-in. If it did, this would become incredibly simple: array3.find_all_indices { |list| list.include? course }, but sadly such a method does not appear to exist.
Great thing about Ruby is if you don't like that, you can just patch it in!
@SilvioMayolo It does now have filter_map so array3.each_with_index.filter_map {|list,i| i if list.include? course } but still a bit of a mouthful in comparison.
|
0

You can achieve this with each

array3 =['Maths', 'Programming', 'Physics'], ['Maths', 'Intro to comp. science', 'Programming'], ['English', 'Intro to comp. science', 'Physics']
course = 'Programming'    
index = []
array3.each do |i|
    if i.include?(course)
        index << i
    end
end

2 Comments

Did you run this?
yes of course. In irb. And in the end index contains the 2 elements of the array.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.