1

I've got:

@fruit = ["Apples, Oranges, Bananas", "Apples", "Bananas, Pears", "Bananas, Apples, Pears", "Pears"]

I want to do two different things with this, first turn it into a pure array with only one instance of each:

["Apples", "Oranges", "Bananas", "Pears"]

Secondly I want to be able to determine how many of a given instance there are in the array:

@fruit.count("Apples") = 3

Thirdly, is it possible to order the array by the number of instances:

@fruit.sort = ["Apples", "Apples", "Apples", "Bananas", "Bananas", "Bananas", "Pears", "Pears", "Pears", "Oranges"]

What array/string functions would I have to use to do this?

4 Answers 4

6
arr = ["Apples, Oranges, Bananas", "Apples", "Bananas, Pears", "Bananas, Apples, Pears", "Pears"]

hsh = Hash.new { |h, k| h[k] = 0 }

arr.each do |str|
  fruits = str.split(/, /)
  fruits.each do |fruit|
    hsh[fruit] += 1
  end
end

p hsh.keys
# => ["Apples", "Oranges", "Bananas", "Pears"]

hsh.keys.each { |fruit| puts "#{fruit}: #{hsh[fruit]}" }
# => Apples: 3
# => Oranges: 1
# => Bananas: 3
# => Pears: 3
Sign up to request clarification or add additional context in comments.

2 Comments

first of all, this shows a great and underused feature of Hash.new -> +1. and second, this saves you some loops. remember that each enumerator method: map, flatten, uniq and count all take at least 1 iteration over your array.
@marian: don't worry about performance too soon. Functional constructions (map/select/flatten) promote good code, while loops using custom imperative eachs are harder to understand.
4
@fruit = ["Apples, Oranges, Bananas", "Apples", "Bananas, Pears", "Bananas, Apples, Pears", "Pears"]

@fruits = @fruit.map{|f| f.split(", ")}.flatten
#=>["Apples", "Oranges", "Bananas", "Apples", "Bananas", "Pears", "Bananas", "Apples", "Pears", "Pears"]
@fruits.uniq
#=> ["Apples", "Oranges", "Bananas", "Pears"]
@fruits.count{|f| f=="Apples"}
#=>3

1 Comment

perfect! Flatten, that's what I didn't know! Thanks.
2

A hash is the better data structure to do this:

@fruit = ["Apples, Oranges, Bananas", "Apples", "Bananas, Pears", "Bananas, Apples, Pears", "Pears"]

h = Hash.new

@fruit.each do |str|
  str.split(/,/).each do |f|
    f.strip!
    h[f] ||= 0
    h[f] += 1
  end
end


h.keys
 => ["Apples", "Oranges", "Bananas", "Pears"] 

h
 => {"Apples"=>3, "Oranges"=>1, "Bananas"=>3, "Pears"=>3} 

h["Apples"]
 => 3

you can then process the accumulated data in the hash to print out a sorted array if you need one.

Comments

0
@fruit = ["Apples, Oranges, Bananas", "Apples", "Bananas, Pears", "Bananas, Apples, Pears", "Pears"]

p @fruit.map{|f| f.split(', ') }.flatten.uniq
#=> ["Apples", "Oranges", "Bananas", "Pears"]

p @fruit.count{|f| f.include?("Apples")}
#=> 3

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.