Hey! where's #count?

i went to count the number of equal objects in an array and discoverd
there was no #count. that was odd, i thought, there’s one for string.
but then it occured to me, #count would be in Enumberable. but no. it is
not. hey! why not?

···


~transami

__("< berk! berk!
__/
^^

i went to count the number of equal objects in an array and discoverd
there was no #count. that was odd, i thought, there’s one for string.
but then it occured to me, #count would be in Enumberable. but no. it is
not. hey! why not?

use Enumerable#select

obj.select {|item| item==str}.size

or

count=0
obj.each {|item| count += 1 if item==str}
count

···


MoonWolf moonwolf@moonwolf.com

In article 1026539829.17347.110.camel@silver,

···

Tom Sawyer transami@transami.net wrote:

i went to count the number of equal objects in an array and discoverd
there was no #count. that was odd, i thought, there’s one for string.

I needed this same functionality the other day and ended up writing a
function. It does seem like it should be in Array.

Phil

“Tom Sawyer” wrote in

i went to count the number of equal objects in an array and discoverd
there was no #count. that was odd, i thought, there’s one for string.
but then it occured to me, #count would be in Enumberable. but no. it is
not. hey! why not?

I guess I would write #count (not sure if this is such a descriptive
name) as

class Array
def count() uniq.size end
end

Thinking about it, there is seems to be a good argument to move
#uniq, with possible addition of #count (as I said I don’t like
that name), from the Array class to the Enumerable module
since the uniq algorithm (of class Array)

module Enumerable
def uniq
hsh = {}
each {|e| hsh[e] = true }
hsh.keys
end
end

only relies on each.

/Christoph

indeed, i used select. i was just sort of surprised that #count wasn’t
in Enumberable. #include? is there, as is #select --what you suggest to
use to do the count.

~transami

···

On Sat, 2002-07-13 at 06:05, MoonWolf wrote:

i went to count the number of equal objects in an array and discoverd
there was no #count. that was odd, i thought, there’s one for string.
but then it occured to me, #count would be in Enumberable. but no. it is
not. hey! why not?

use Enumerable#select

obj.select {|item| item==str}.size

or

count=0
obj.each {|item| count += 1 if item==str}
count


MoonWolf moonwolf@moonwolf.com


~transami

__("< berk! berk!
__/
^^

module Enumerable
    def uniq
        hsh = {}
        each {|e| hsh[e] = true }
        hsh.keys
    end
end

Do you expect this ?

pigeon% cat b.rb
#!/usr/bin/ruby
module Enumerable
   def uniq
      hsh = {}
      each {|e| hsh[e] = true }
      hsh.keys
   end
end

a = {"a" => 12, 12 => "a"}
b = a.uniq
p b, b.type
pigeon%

pigeon% b.rb
[[12, "a"], ["a", 12]]
Array
pigeon%

Guy Decoux

hi Christoph,

I guess I would write #count (not sure if this is such a descriptive
name) as

class Array
def count() uniq.size end
end

the String definition of count is different from what you have here. in
the String class it returns the number of occurances of a given
sub-string, but is also a little more sophistacted, offering the option
for a string range, string negation, and multiple strings to be matched.
this would makes count difficult to implement in Enumerable, and also
relates to the strange definition of String#each. but a simple
definition would be:

module Enumberable
def count(c)
self.select { |i| i == c }.length
end
end

this works fine for array, and i imagine most other Enumberable mixin
classes. for string it is a little odd, counting matches against
segments of the string split by the record seperator $/. making it
useless to count characters, which is often what one would want. (hence
another reason to modifiy each as per our recent thread) anyway, while i
believe this inclusion of count in Enumberable is sensible and
practical, either the String’ss version of count would have to be
overridden to reamin compatible with the current count, or another name
would need to be used in Enumberable case, like #number_of, although i
point out that the above count method can be “spruced-up” to handle all
but String#count’s alphanumeric ranges. (i don’t see how ranges could
apply to arrays, for instance)

module Enumerable
def uniq
hsh = {}
each {|e| hsh[e] = true }
hsh.keys
end
end

again for a string this returns slightly odd results due to strings
unique definition of #each. but i do see your reasoning and think there
is no reason #uniq can not also be fashioned into Enumberable.

···

On Sun, 2002-07-14 at 06:01, Christoph wrote:


~transami

__("< berk! berk!
__/
^^

“ts” wrote in

Do you expect this ?

Yes (I actually tested my snippet on a Hash example
to make sure that it works this way - nonetheless if I
were to vote on this as an RCR I’d vote against it since
it doesn’t seem useful enough to put in Enumerable)

pigeon% cat b.rb
#!/usr/bin/ruby
module Enumerable
def uniq
hsh = {}
each {|e| hsh[e] = true }
hsh.keys
end
end

a = {“a” => 12, 12 => “a”}
b = a.uniq
p b, b.type
pigeon%

pigeon% b.rb
[[12, “a”], [“a”, 12]]

/Christoph

“Tom Sawyer” wrote

the String definition of count is different from what you have here. in
the String class it returns the number of occurances of a given
sub-string, but is also a little more sophistacted, offering the option
for a string range, string negation, and multiple strings to be matched.
this would makes count difficult to implement in Enumerable, and also
relates to the strange definition of String#each. but a simple
definition would be:

module Enumberable
def count(c)
self.select { |i| i == c }.length
end
end

Aha, I see what you mean

this works fine for array, and i imagine most other Enumberable mixin
classes. for string it is a little odd, counting matches against
segments of the string split by the record seperator $/. making it
useless to count characters, which is often what one would want. (hence
another reason to modifiy each as per our recent thread) anyway, while i
believe this inclusion of count in Enumberable is sensible and
practical, either the String’ss version of count would have to be
overridden to reamin compatible with the current count, or another name
would need to be used in Enumberable case, like #number_of, although i
point out that the above count method can be “spruced-up” to handle all
but String#count’s alphanumeric ranges. (i don’t see how ranges could
apply to arrays, for instance)

The problem is that some Enumerable classes like the Hash class or
a Set class (see for example rough/lib/set.rb - OT I am not sure why
this implementation doesn’t include Comparable) don’t know the
about the idea of multiple occurrences consequently you would
optimize #count to

def count(c)
each {|e| return 1 if e == c }
return 0
end

which is sort of an indication (to me) that #count doesn’t really into
Enumerable …

/Christoph

Considering Enumerables like Set or Hash as a degenerated Enumerable I
find #count makes sense in Enumberable. Hash or Set can easily provide
optimized versions of #count. It like find for a sorted list which can
Mixin Enumerable and nevertheless have an optimized implementation of
#min and #max

-billy.

···

On Sun, Jul 14, 2002 at 11:41:55PM +0900, Christoph wrote:

The problem is that some Enumerable classes like the Hash class or
a Set class (see for example rough/lib/set.rb - OT I am not sure why
this implementation doesn’t include Comparable) don’t know the
about the idea of multiple occurrences consequently you would
optimize #count to

def count(c)
each {|e| return 1 if e == c }
return 0
end

which is sort of an indication (to me) that #count doesn’t really into
Enumerable …


Meisterbohne Söflinger Straße 100 Tel: +49-731-399 499-0
eLösungen 89077 Ulm Fax: +49-731-399 499-9

From: Philipp Meier [mailto:meier@meisterbohne.de]
Sent: Sunday, July 14, 2002 5:20 PM
To: ruby-talk ML
Subject: Re: hey! where’s #count?

The problem is that some Enumerable classes like the Hash class or
a Set class (see for example rough/lib/set.rb - OT I am not sure why
this implementation doesn’t include Comparable) don’t know the
about the idea of multiple occurrences consequently you would
optimize #count to

def count(c)
each {|e| return 1 if e == c }
return 0
end

which is sort of an indication (to me) that #count doesn’t really
into
Enumerable …

Considering Enumerables like Set or Hash as a degenerated Enumerable I
find #count makes sense in Enumberable. Hash or Set can easily provide
optimized versions of #count. It like find for a sorted list which can

True - I guess my point was that the Hash/Set degeneration is so
common, that it is hard to speak(write) about “degeneration”.

/Christoph

···

-----Original Message-----
On Sun, Jul 14, 2002 at 11:41:55PM +0900, Christoph wrote:

so i tried my hand at including count in Enumberable and “normalizing”
String and Hash accordingly. take a look at the attached script to see
how the current design is a tad odd, versus how these changes effect it.

module Enumerable
def count(c)
self.select { |i| i == c }.length
end
end

class String
alias contains count
remove_method :count
def each
each_byte { |c| yield c.chr }
end
end

class Hash
remove_method :include?

each is synonomous with each_value, not each_pair

alias each each_value

include key shoud be the primary method, has_key the alias but…

alias include_key? has_key?

ditto for value

alias include_value? has_value?
def include_pair?
# detect_pair …?.. now we start getting bushwacked :slight_smile:
end
end

for String, #conatins will do what #count use to. i also redefined #each
to be each character, so then one would need to use use #each_line for
what #each used to mean (we could have just redefined what record
seperator ‘’ means, but would require $/ take regexps to compensate for
what ‘’ used to mean)

Hash is seriously inept at being normalized, as #include? should be
synonomous with has_value? and #count? should count on values. thus
#each needs to mean #each_value. trying to “normalize” Hash leads to
filling it with all sorts of methods: #detect_key, #detect_pair,
#count_key, #count_pair…etc." This all stems from the fact that Hash
isn’t really Enumberable. #each_with_index, for instance, is
meaningless, since a Hash is unordered, and the components of a Hash,
the pairs (x=>y) aren’t true objects in themselves.

for starters, anaylizing this in depth has led me to beleive that
Enumberable itself really is a intersection of two different types of
mixins. On the one hand everthing realated to #each partakes of their
own mixin called, say, Iterable. then the methods involving <=> (and ==
actually) would be left in Enumerable which also mixes-in Iterable. thus
hash is Iterable, but it is not Enumberable. this distinction would help
clear up “degeneration”, and the seperation could be useful elsewhere,
perhaps in Set, for instance.

but then there is the consideratin that x=>y, the Hash pairs may best
symbolize real objects, x=>y being the literal form. actually it is odd
that they don’t with ruby being 100% OO. is there any other such thing
in ruby? having the hash pairs as objects would actually make ordered
hashes pretty easy to make: [ x1=>y1, x2=>y2, … ] they are just arrays
of these pairs, and in fact may be capable of replacing Hash
altogether.(?)

class HashPair
attr_reader :index, :value
def initialize
@index
@value
end

… whatever methods make sense

end

HashPair may not be the best name. what do you call them? but you get
the idea. i’m very interested on hearing your thoughts on this.

~transami

t2.rb (2 KB)

···

On Sun, 2002-07-14 at 09:34, Christoph wrote:

-----Original Message-----
From: Philipp Meier [mailto:meier@meisterbohne.de]
Sent: Sunday, July 14, 2002 5:20 PM
To: ruby-talk ML
Subject: Re: hey! where’s #count?

On Sun, Jul 14, 2002 at 11:41:55PM +0900, Christoph wrote:

The problem is that some Enumerable classes like the Hash class or
a Set class (see for example rough/lib/set.rb - OT I am not sure why
this implementation doesn’t include Comparable) don’t know the
about the idea of multiple occurrences consequently you would
optimize #count to

def count(c)
each {|e| return 1 if e == c }
return 0
end

which is sort of an indication (to me) that #count doesn’t really
into
Enumerable …

Considering Enumerables like Set or Hash as a degenerated Enumerable I
find #count makes sense in Enumberable. Hash or Set can easily provide
optimized versions of #count. It like find for a sorted list which can

True - I guess my point was that the Hash/Set degeneration is so
common, that it is hard to speak(write) about “degeneration”.

/Christoph


~transami

(") dobee dobee do…
\v/
^ ^

Hi –

so i tried my hand at including count in Enumberable and “normalizing”
String and Hash accordingly. take a look at the attached script to see
how the current design is a tad odd, versus how these changes effect it.

[…]

Hash is seriously inept at being normalized, as #include? should be
synonomous with has_value? and #count? should count on values. thus
#each needs to mean #each_value. trying to “normalize” Hash leads to

I don’t get the “should” part… Having #include? do something
different from #has_value? shouldn’t be a problem, since #has_value?
is available. (That argument doesn’t count for much if #include? is
doing something inherently bad, but I don’t think it is.) It’s not a
winner-take all situation :slight_smile:

filling it with all sorts of methods: #detect_key, #detect_pair,
#count_key, #count_pair…etc." This all stems from the fact that Hash
isn’t really Enumberable. #each_with_index, for instance, is
meaningless, since a Hash is unordered, and the components of a Hash,
the pairs (x=>y) aren’t true objects in themselves.

I completely agree. In fact, see the thread starting at
[ruby-talk:11272]. Even now, I still don’t think I’ve ever seen
Hash#each_with_index used, nor have I ever been able to think of a
hypothetical case where one would use it (since the idea of retrieving
unordered elements in numerical “order” is inherently useless).

I don’t know whether it merits language-level change, since it can
always just be ignored (it’s sort of inert, in that sense), though my
instincts, like yours, are to see Enumerable as something of an
amalgam of something like Enumerable and Iterable. There’s been at
least some chatting about this here (and I thought there was a little
bit recently, but I couldn’t find it) – search on “iterable” at
ruby-talk.org and you’ll see some comments.

David

···

On Mon, 15 Jul 2002, Tom Sawyer wrote:


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav

meaningless, since a Hash is unordered, and the components of a Hash,

  An Hash is ordered, this is just that the order is difficult to predict.

Try to call #each many times, and you'll see that the (key, value) are
always given in the same order (if you don't modify the hash).

Guy Decoux

thanks david!

I don’t get the “should” part…

i just mean “should” as in what seems most “common sense”, though not
always the same for everyone, but in general, for instance, if i call
#include? on a Hash, it makes sense if it checks the values like Array
does, not the index. that’s all.

no i’m not saying there’s something wrong with the way these things
work, obviously they work and are useable. only that i think it is
better the more consitent things are, across the board. not only for
being more “intuitive”, but you’ll notice in my humble attempt at
“normalizing” that more method definitons are removed, hence a cleaner
tighter system.

i beleive it was einstien who said “simplify! but not too simple.” okay,
that’s a paraphrase. but the idea is that it is important to simplify
matters as much as possible, just as long as the comparable
functionality remains.

i’ll definitly check out the threads and comments. thanks again!

~transami

···

On Sun, 2002-07-14 at 20:02, David Alan Black wrote:

Hi –

On Mon, 15 Jul 2002, Tom Sawyer wrote:

so i tried my hand at including count in Enumberable and “normalizing”
String and Hash accordingly. take a look at the attached script to see
how the current design is a tad odd, versus how these changes effect it.

[…]

Hash is seriously inept at being normalized, as #include? should be
synonomous with has_value? and #count? should count on values. thus
#each needs to mean #each_value. trying to “normalize” Hash leads to

I don’t get the “should” part… Having #include? do something
different from #has_value? shouldn’t be a problem, since #has_value?
is available. (That argument doesn’t count for much if #include? is
doing something inherently bad, but I don’t think it is.) It’s not a
winner-take all situation :slight_smile:

filling it with all sorts of methods: #detect_key, #detect_pair,
#count_key, #count_pair…etc." This all stems from the fact that Hash
isn’t really Enumberable. #each_with_index, for instance, is
meaningless, since a Hash is unordered, and the components of a Hash,
the pairs (x=>y) aren’t true objects in themselves.

I completely agree. In fact, see the thread starting at
[ruby-talk:11272]. Even now, I still don’t think I’ve ever seen
Hash#each_with_index used, nor have I ever been able to think of a
hypothetical case where one would use it (since the idea of retrieving
unordered elements in numerical “order” is inherently useless).

I don’t know whether it merits language-level change, since it can
always just be ignored (it’s sort of inert, in that sense), though my
instincts, like yours, are to see Enumerable as something of an
amalgam of something like Enumerable and Iterable. There’s been at
least some chatting about this here (and I thought there was a little
bit recently, but I couldn’t find it) – search on “iterable” at
ruby-talk.org and you’ll see some comments.

David


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav


~transami

(") dobee dobee do…
\v/
^ ^

An Hash is ordered, this is just that the order is difficult to
predict.

certanly it has order internally, but that order is not at all given to
control by the programmer. yes, it will always come out in the same
order, but there’s no garuntee what that order will be, hence for all
programmable purposes it is unordered.

cheers,
transami

···

On Mon, 2002-07-15 at 02:29, ts wrote:

meaningless, since a Hash is unordered, and the components of a Hash,

An Hash is ordered, this is just that the order is difficult to predict.

Try to call #each many times, and you’ll see that the (key, value) are
always given in the same order (if you don’t modify the hash).

Guy Decoux


~transami

(") dobee dobee do…
\v/
^ ^

certanly it has order internally, but that order is not at all given to
control by the programmer. yes, it will always come out in the same
order, but there's no garuntee what that order will be, hence for all
programmable purposes it is unordered.

Well, try #each, #keys and #values and you'll see that the objects are
given in the same order : this is (for me) important

Guy Decoux

ts,

how do you utilize that order? do you read it out to see what order it
is in and then store that order for later use?

~transami

···

On Mon, 2002-07-15 at 03:04, ts wrote:

certanly it has order internally, but that order is not at all given to
control by the programmer. yes, it will always come out in the same
order, but there’s no garuntee what that order will be, hence for all
programmable purposes it is unordered.

Well, try #each, #keys and #values and you’ll see that the objects are
given in the same order : this is (for me) important

Guy Decoux


~transami

(") dobee dobee do…
\v/
^ ^

ts wrote:

programmable purposes it is unordered.

Well, try #each, #keys and #values and you’ll see that the objects are
given in the same order : this is (for me) important
Guy Decoux

Be careful with that assumption. I believe that as a hash expands it
occasionally needs to re-hash it’s keys, and that would alter the order.
I don’t know that Ruby’s hash works that way, but most of the ones I’ve
encountered do.

···


– Charles Hixson
Gnu software that is free,
The best is yet to be.

how do you utilize that order?

I use it in this case

Well, try #each, #keys and #values and you'll see that the objects are
given in the same order : this is (for me) important

Guy Decoux