1

Constructing a basic address book in Ruby. I have the following line of code in my program that iterates over the existing array(@address_book) based on a standard numeric input (entrynumber) to match the array index. The resulting value that matches that index is then returned. Here's the code in question:

     puts @address_book.entries.each_with_index.select {|val, i| i == (entrynumber - 1)}

the results look great except that the index is also returned at the bottom, like this: (note 0 at the end of return) I'd ideally like the index number itself at the bottom not returned.

View by Entry Number
Entry Number: 1
You picked 1
Name: adam adams
Phone Number: 111-111-1111
Email: [email protected]
0

What am I missing in terms of returning the value, but without the index?

2
  • Can you share to_s method of address_book class Commented Jul 23, 2015 at 20:33
  • Is it not just @address_book.entries[entrynumber-1]? Commented Jul 23, 2015 at 21:04

2 Answers 2

2

The problem

The trouble is that each_with_index is turning @address_book.entries into an array of arrays. Here's an example of what I mean:

["a", "b"].each_with_index.to_a
# => [["a", 0], ["b", 1]] 

So when you apply select to each_with_index, the selected elements are each going to be an array with the element and its index:

["a", "b"].each_with_index.select { |e, i| i == 1 }
=> [["b", 1]] 

A bad fix

You could fix that by using #map to select only the first element of each selected row:

["a", "b"].each_with_index.select { |e, i| i == 1 }.map(&:first)
 => ["b"] 

Using select.with_index

Better still, you could use select.with_index:

["a", "b"].select.with_index { |e, i| i == 1}
 => ["b"] 

Or, in the case of your code:

@address_book.entries.
  each_with_index.select.with_index {|val, i| i == (entrynumber - 1)}

Using Array#[]

If @address_book.entries is an array, then you can index the array, not using select at all:

@address_book_entries[entrynumber - 1]

If it's not an array, you can turn it into one with #to_a:

@address_book.entries.to_a[entrynumber - 1]

However, if @address_book.entries is large, this could use a lot of memory. Be careful when turning an enumeration into an array.

Sign up to request clarification or add additional context in comments.

Comments

0

It seems like what you want it to get a single item which isn't really what select is best suited for (especially when you're retrieving it via an index. I would probably do something like:

@address_book.entries.to_a[entrynumber - 1]

Comments

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.