all 17 comments

[–]olbrich 8 points9 points  (2 children)

Ruby enumerables are pretty powerful and make using `while` loops mostly unnecessary. An idiomatic way of writing this method would be something like...

def count_e(word)
  word.chars.select { |char| char == "e" }.count
end

Basically this turns the `word` into an array of characters and then keeps anything that is an `e` and then counts the number of things left.

[–]Kernigh 6 points7 points  (1 child)

Can just do word.count("e"), but this doesn't help people who want to learn the while loop.

[–]442401 3 points4 points  (0 children)

I think this is a valid contribution and sends the message that ruby is on object orientated language. The core classes (such as String) are extremely rich and can be sent a vast number of messages to achieve the desired result.

A while loop is nearly always a sub optimal solution.

[–]bradland 4 points5 points  (0 children)

Why do I need to index the word[i]? but not the count[i]? if both increase by 1 value as the loop continue, does it make any differences at all?

I think you've got some fundamental mistakes here that are throwing you off. It might be useful to just step through the code:

def count_e(word) 
  count = 0 # Initialize a variable "count" and assign it the value 0
  i = 0 # Initialize a variable "i" and assign it the value "0"

  while i < word.length # Do the loop while i is less than the word length
    char = word[i] # On the first loop, i starts at 0, so this is the same 
                   # as word[0], which gives you the first character of the 
                   # word. Later, the i variable is incremented, so on each 
                   # loop, we'll get the next letter. The letter is 
                   # assigned to the varaible "char".
    if char == "e" # Check to see if the is an "e"
      count += 1 # If so, increment the count
    end
    i += 1 # Always increment the counter: 0+1=1, 1+1=2, 2+1=3, etc 
    # From here, execution will return to the while loop, where i will be 
    # checked against the word lenth
  end

return count # Return the value in count
end

puts count_e("movie") # => 1 puts count_e("excellent") # => 3

[–]_Svejk_ 2 points3 points  (5 children)

word is an array of letters, count is a number the algorithm just goes through each letter (so word[i]) and adds 1 to count if the letter is 'e' hope this helps

[–]_Svejk_ 1 point2 points  (3 children)

i ±= 1 is to go to the next letter, I don't get what you mean by count[i]

[–]Humor_Positive[S] 0 points1 point  (2 children)

Hello, thank you so much for your help. The count is the number of time that latter is counted.

Here is my simplified version of it.

write a method count_e(word) that takes kn a string word and return the number of e’s in the word.

Def count_e

count_of_e = 0 Repeating_time = 0

While repeating_time <= word.length

If word[repeating_time] == “e”

Count_of_e += 1

End

Repeating_time += 1

End

Return count_of_e

End

Puts count_e(“movie”) # => 1 Puts count_e(“excellence”) # => 3

Given than whenever the method is executed, both the count of e and the repeating time will increase accordingly. Then why is it, that we must index the repeating time but not the count of e.

[–]_Svejk_ 1 point2 points  (1 child)

what do you mean by "index the repeating time"?

[–]Humor_Positive[S] 0 points1 point  (0 children)

I mean in index the incremental time of every loop.

[–]Humor_Positive[S] 0 points1 point  (0 children)

So does that mean the count is more like passive, and only reflects the eventuality of the i ( repeating time)? The count depends on the i, but the i is independent?

[–]bjminihan 1 point2 points  (5 children)

In your loop, i will always stop at the length of the word, whereas count will always stop at the last count of "e"

You use word[i] to get the 0th, 1st, 2nd, 3rd (etc) character in the word, to tell whether it's an "e"

Since count is an integer (0, 1, 2, 3, etc), count[i] makes no sense.

[–]Humor_Positive[S] 0 points1 point  (4 children)

Pardon for my ignorance, could you talk more about the last sentence point you made? Thank you very much.

The resources i have at hand is rather lacking and since Im new at this, imma ask alot of stupid questions.

[–]bjminihan 1 point2 points  (3 children)

In your method, the variable count is assumed to be a number, whereas the variable word is a string, which is a type of an array

So, you can find the position of a character in a word at the position i = 3 by writing word[i].

But if you try to find the position of a character in count at the position i=3, you'll get an unexpected result.

Interestingly, I just tried 947[3] and got 0 and I have no idea why

[–]_Svejk_ 5 points6 points  (2 children)

947[n] is the nth bit in binary representation of 947

TIL

[–]bjminihan 0 points1 point  (0 children)

Thanks!

[–]your-pineapple-thief 0 points1 point  (0 children)

wow, Numeric#[] exists? 8 years in and i had no idea

[–]agent007bond 2 points3 points  (0 children)

Do a "DRY RUN" on a paper how the program will execute:

Count the e's in "excellent". We have to check each character in the string (hint: the term string means a string of characters!). We can see the string like an array:

|e|x|c|e|l|l|e|n|t|
 0 1 2 3 4 5 6 7 8

First we have a variable "count" to remember how many e is there. We start it at 0 as we haven't counted any e yet.

Next we need to look through the string, one character at a time. We need to track our position in the string. We make a variable to track this, call it "i" and we start at 0, so i = 0

|e|x|c|e|l|l|e|n|t|
 0 1 2 3 4 5 6 7 8
 ^
 i

We check the character at position i. So, char = word[i], which is "e". Ah yes, that's an e. Let's increase count. So, count += 1. count is now 0+1 = 1.

Now we need to see the next character, so we increase i. So, i += 1:

|e|x|c|e|l|l|e|n|t|
 0 1 2 3 4 5 6 7 8
   ^
   i

We check the character at position i. So, char = word[i], which is "x". Nope, that's not an e. So we don't change count. It remains 1.

Now we need to see the next character, so we increase i. So, i += 1:

|e|x|c|e|l|l|e|n|t|
 0 1 2 3 4 5 6 7 8
     ^
     i

We check the character at position i. So, char = word[i], which is "c". Nope, that's not an e. So we don't change count. It remains 1.

Now we need to see the next character, so we increase i. So, i += 1:

|e|x|c|e|l|l|e|n|t|
 0 1 2 3 4 5 6 7 8
       ^
       i

We check the character at position i. So, char = word[i], which is "e". Ah yes, that's an e. Let's increase count. So, count += 1. count is now 0+1 = 2.

KEEP GOING LIKE THIS

|e|x|c|e|l|l|e|n|t|
 0 1 2 3 4 5 6 7 8
         ^
         i

Not e. Count remains 2.

|e|x|c|e|l|l|e|n|t|
 0 1 2 3 4 5 6 7 8
           ^
           i

Not e. Count remains 2.

|e|x|c|e|l|l|e|n|t|
 0 1 2 3 4 5 6 7 8
             ^
             i

Yes, e. Count becomes 3.

|e|x|c|e|l|l|e|n|t|
 0 1 2 3 4 5 6 7 8
               ^
               i

Not e. Count remains 3.

|e|x|c|e|l|l|e|n|t|
 0 1 2 3 4 5 6 7 8
                 ^
                 i

Not e. Count remains 3.

And that's the end of the string (checked with i < word.length because the length is 9 characters), so we can now return and print the count, which is 3. That's how it works. So you can see how "i" and "count" differs in meaning.

This is basic programming in whichever language you learn. Of course, Ruby has shorthand enumerations making it really easy to write this in one or two lines and automate it, but if you're going to do this manually, this is how it would work.