How does count method works in Ruby?
Just imagine the "pattern" strings as wrapped by [
and ]
from regex syntax, that are matched against each character.
So, if we break a = "hello world"
into characters:
[1] pry(main)> a = "hello world"
=> "hello world"
[2] pry(main)> a.split('')
=> ["h", "e", "l", "l", "o", " ", "w", "o", "r", "l", "d"]
And convert "ej-m" to regex wrapped with [
and ]
we get /[ej-m]/
- which means either 'e'
or any character from 'j'
to 'm'
(including both):
[3] pry(main)> a.split('').select{|c| c=~ /[ej-m]/}
=> ["e", "l", "l", "l"]
We got 4 matches - which is also the result you get. Essensially a.count "ej-m"
is equivalent to:
[4] pry(main)> a.split('').count{|c| c=~ /[ej-m]/}
=> 4
Multiple arguments to the method are just and
between the matches:
[5] pry(main)> a.split('').count{|c| c =~ /[hello]/ and c =~ /[^l]/}
=> 4
How does count work in Ruby
According the documentation, count(p1)
for Array
Returns the number of elements. If an argument is given, counts the number of elements which equals to obj. If a block is given, counts the number of elements yielding a true value.
In your case, sentence.downcase.split
gives you ["to", "be", "or", "not", "to", "be"]
. Here, you have two array elements equaling "to"
, that's why you obtain 2
.
From the documentation of String
, count(*args)
Each other_str parameter defines a set of characters to count. The intersection of these sets defines the characters to count in str. Any other_str that starts with a caret (^) is negated. The sequence c1–c2 means all characters between c1 and c2.
If we put aside the negation case, given a String
parameter p, call count
on a String
x returns the number of characters in x matching one of the characters of p.
In your case, you have "llool"
in "hello world"
matching "lo"
, i.e. 5
The string count() method
"hello world".count("lo")
returns five. It has matched the third, fourth, fifth, eighth, and tenth characters. Lets call this set one.
"hello world".count("o")
returns two. It has matched the fifth and eighth characters. Lets call this set two.
"hello world".count("lo", "o")
counts the intersection of sets one and two.
The intersection is a third set containing all of the elements of set two that are also in set one. In our example, both sets one and two contain the fifth and eighth characters from the string. That's two characters total. So, count
returns two.
How do I recreate Enumerable's count method?
Don't use a default argument. Use *args
to collect all the arguments into an array.
def my_count(*args, &block)
if args.length == 1 && !block_given?
# use args[0]
elsif args.length == 1 && block_given?
# use block
elsif args.length == 0 && !block_given?
# no argument/block
else
# raise error
end
end
calling the method 'count' returns wrong number of arguments
I think this is what you were trying to do
def timed_reading(max_length, text)
text.split.delete_if { |y| y.length >= max_length }.count
end
You could just count words with length less than the max anyway
text.split.count { |y| y.length < max_length }
Count initializations of Ruby Class
Instance variables belong to objects (aka instances), that's why they are called instance variables after all. Your first @bar
is an instance variable of Foo
, your second @bar
is an instance variable of the newly-created instance of Foo
. Those are two completely different objects (they aren't even of the same class: the newly-created instance is of class Foo
, whereas Foo
is of class Class
).
You obviously need to increment @bar
in a method called on Foo
, not in a method called on instances of Foo
. So, can we think about a method that is a) called on Foo
and b) called everytime an instance is created? What about new
?
class Foo
@bar = 0
def self.new(*)
@bar += 1
super
end
end
Okay, technically speaking, this doesn't count the number of instances, only the number of times new
was called. Sometimes, instances get created without calling new
, e.g. when de-serializing. This should be the closest you can get without resorting to ugly hacks of the interpreter internals.
You might think you can override allocate
instead (I thought so, too), but I just tested it and it doesn't work. Presumably, the default implementation of new
doesn't call allocate
via normal means but actually uses the interpreter internal implementation directly.
How to count instances of class without counting reassignment?
In the real world you wouldn't be counting instances in memory, you'd be asking a database how many exist. You need to think in terms of a database.
Your use of a
to repeatedly contain the Ticket instance is wrong. You should be using an Array, Hash or Set to maintain the list, then ask the container how many exist:
require 'set'
class Ticket
attr_accessor :price
attr_reader :event, :venue
@@tickets = Set.new
def initialize(event, venue)
@event = event
@venue = venue
@@tickets << self
end
def delete
@@tickets.delete(self)
end
def self.count
@@tickets.size
end
end
a = Ticket.new("Michael Buble", "Staples")
b = Ticket.new("Frank Sinatra", "Madison Square Garden")
puts "Ticket count of #{Ticket::count}"
b.delete
puts "Ticket count of #{Ticket::count}"
You can build this out by adding ways to retrieve a particular instance from @@tickets
, add a to_s
so you can list them, but, in the end, you'll want to use a real database. If your code were to crash for any reason, your entire list of tickets would disappear, which would be unacceptable in real life.
Related Topics
What Does This Mean in Ruby Language
Error Installing "Kgio-2.9.2" Gem on Windows
Rake Aborted! Undefined Method 'Migration_Error=' for Activerecord::Base:Class
Ruby: How to Convert Ip Range to Array of Ip'S
Rails Reload Dynamic Routes on Multiple Instances/Servers
Tinytds Error: Adaptive Server Connection Timed Out
What Do Ruby's Printf Arguments Mean
Nesting Too Deep' Error While Retrieving JSON Using Httparty
How to Programmatically Convert Mp3 to an Itunes-Playable Aac/M4A File
How to Access Current_User Object in Model
Selenium2 Webdriver Ruby => How Click on a Hidden Link
Product Orders Between 2 Users
How to Execute 2 or More Commands in the Same Ssh Session
Why Does Hash#Select and Hash#Reject Pass a Key to a Unary Block
How to Run Perl and Ruby Scripts as Tasks in Ant