Reputation: 2363
I am trying build a sentence out of 3 arrays with the count of each array.
cats = Cat.all
dogs = Dog.all
birds = Bird.all
animals = ["#{cats.count} Cats", "#{dogs.count} Dogs", "#{birds.count} Birds"]
sentence = animals.each.map{ |r| r }.join(", ")
Right now, this works, but if I have no cats sentence outputs to
"O Cats, 5 Dogs, 4 Birds"
and I'ld like it to just say:
"5 Dogs & 4 Birds"
or, at the very least:
"5 Dogs, 4 Birds"
I feel like I might need to use an array of hashes, but I'm a bit lost.
Upvotes: 0
Views: 51
Reputation: 8888
Yes, you need a hash.
cats = Cat.all
dogs = Dog.all
birds = Bird.all
animals = {
cats: cats.count,
dogs: dogs.count,
birds: birds.count
}
sentence = animals.reject{|k, v| v.zero?}
.map{|k, v| "#{v} #{k.to_s.capitalize}"}
.join(', ')
My suggestion: keep data as data till the last moment, so that you can have maximum flexibility to display it in various ways. I feel that the animals
in your code thinks rendering too soon.
Upvotes: 3
Reputation: 10434
To get "5 Dogs, 4 Birds"
, you can do
sentence = animals.each.map{ |r| /^0\s/.match(r) ? nil : r }.compact.join(", ")
The regex matches anything that starts with 0
and a space. If there is a match, return nil, or return the original string. The compact
method removes nil
elements from the array, and finally you join the elements.
If you want 5 Dogs & 4 Birds
, you can define a method that performs that function.
def english_join(array)
return array.to_s if array.nil? or array.length <= 1
array[0..-2].join(", ") + " & " + array[-1]
end
Then you can do
sentence = english_join(animals.each.map{ |r| /^0\s/.match(r) ? nil : r }.compact)
If you have 0 cats, 5 dogs, and 4 birds, this returns 5 Dogs & 4 Birds
.
If you have 2 cats, 5 dogs, and 4 birds, this returns 2 Cats, 5 Dogs & 4 Birds
Upvotes: 2