tags:

views:

108

answers:

5

I went to http://ruby-doc.org/core/classes/Array.html#M002198 and can't figure out the way to take an array of names for example

people = [chris,george,jerry,bob,bill,julie,josh]

I want to be able to have the user select a letter "b" then hit enter and extract all elements with the first letter 'b' and put them in a seperate array. In this case it would be [bob,bill] The .slice command should work for this but I don't know how to tell it to just look at the first letter of the elements? Would that be some sort of a argument that would need to be filled like this people.slice()

people_selector = gets.chomp.to_s
people.slice(people_selector)
print people

Google is no help either, unfortunately. Post code so I can look at argument values please. Thanks,

Matt

A: 

You'll get more mileage out of collect than you will from slice

http://ruby-doc.org/core-1.9/classes/Array.html#M000444

Azeem.Butt
+8  A: 

You probably want select, not slice:

$ irb
>> people = ["chris", "bob", "bill", "julie"]
=> ["chris", "bob", "bill", "julie"]
>> letter = gets.chomp.downcase
B
=> "b"
>> people.select { |person| person[0,1] == letter }
=> ["bob", "bill"]

Also, there's no need to add the to_s to the gets.chomp; you should already have a string.

In Ruby 1.9, you could instead do:

>> people.select { |person| person[0] == letter }
=> ["bob", "bill"]

In Ruby 1.9, indexing into a string always returns a string; in earlier versions, indexing with a single value into a string gets you a character. Another alternative, which should work in all versions, would be:

>> people.select { |person| person[0] == letter[0] }
=> ["bob", "bill"]
Brian Campbell
Why not simply `person[0]`?
Telemachus
Because person[0] would return the code of the character at the first position.
Lyudmil
I've added some clarification about why you don't do `person[0]`, which actually does work in Ruby 1.9.
Brian Campbell
@Brian: Thanks for the clarification.
Telemachus
+1  A: 

The short answer is that you could use select:

people.select {|person| person[0,1] == letter}

Here is an example implementation. First, we have a unit test describing what needs to happen:

class PeopleListTest < Test::Unit::TestCase
   def setup
      @people = PeopleList.new "jack", "jill", "bruce", "billy"
   end

   def test_starting_with
      assert_equal ["bruce", "billy"], @people.starting_with("b")    
      assert_equal ["jack", "jill"], @people.starting_with("j")    
      assert_equal [], @people.starting_with("q")    
   end
end

If this is what you are attempting to do, then the code to make that pass is:

class PeopleList
   def initialize *people
      @people = people    
   end

   def starting_with letter
      return @people.select {|person| person[0,1] == letter}
   end
end

I hope this helps. Good luck.

Lyudmil
+2  A: 

if you want to remove the elements from the original array as well as put them in a new array, take a look at partition

>> people = "chris,george,jerry,bob,bill,julie,josh".split(",")
=> ["chris", "george", "jerry", "bob", "bill", "julie", "josh"]
>> bs, people = people.partition {|name| name[0,1] == 'b'}
=> [["bob", "bill"], ["chris", "george", "jerry", "julie", "josh"]]
>> bs
=> ["bob", "bill"]
>> people
=> ["chris", "george", "jerry", "julie", "josh"]
Martin DeMello
+1  A: 

This also works, albeit slightly less efficient than Brian's, but much more flexible.

>> a = ['bob', 'abe', 'fred', 'bill']
=> ["bob", "abe", "fred", "bill"]
>> a.select{|s| s =~ /^b/}
=> ["bob", "bill"]
Sam Saffron