Как я могу отобразить вывод Regexp в алфавитном списке? - PullRequest
0 голосов
/ 03 января 2019

Я новичок в программировании и новичок в изучении языка Ruby.Я добился прогресса в своем коде буквенной гистограммы.Сейчас я нахожусь в точке, где я борюсь.

class Letter

  def initialize
    @text = "Hello, World!"
    @letters = Hash.new(0)
  end

  def calculateFrequencies
    @text = text.downcase.chars.each do |c|
      next if c =~ /\s/
      @letters[c] += 1
    end
    puts(@letters)
  end

  def Display

  end 
end

Я создал приложение, которое будет принимать сообщения, введенные пользователем, обрабатывать его и выводить список букв с цифрой, показывающей, как частоэто письмо появилось в сообщении пользователя.Я хотел бы, чтобы выходные данные перечисляли весь алфавит и использовали * для представления того, как часто использовалась эта буква.

Например:

A: **** (For being used 4 times) 
B: ** (For being used 2 times) 
C: (Even if it wasn't used) 
D: * (For being used once) ... and so on all the way to letter Z.

Это мой текущий вывод для "Это тест":

irb(main):019:0> h.calculateFrequency 
{"t"=>3, "h"=>1, "i"=>2, "s"=>3, "a"=>1, "e"=>1}

Ответы [ 2 ]

0 голосов
/ 03 января 2019

Я предлагаю вам построить свой класс следующим образом.

class Letter
  def initialize(text)                                  # 1
    @text = text
  end

  def display
    h = calculate_frequencies                           # 2
    ('a'..'z').each { |ltr|
      puts "%s%s" % [ltr, '*' * h.fetch(ltr, 0)] }      # 3
  end

  private                                               # 4

  def calculate_frequencies                             # 5
    @text.downcase.
          each_char.                                    # 6
          with_object(Hash.new(0)) { |c, letters|       # 7
            letters[c] += 1 if c.match?(/\p{Lower}/) }  # 8
  end
end

str = "Now is the time for all Rubyists to come to the aid of their bowling team."

ltr = Letter.new(str)
ltr.display
a***
b**
c*
d*
e******
f**
g*
h***
i******
j
k
l***
m***
n**
o*******
p
q
r***
s***
t********
u*
v
w**
x
y*
z

Примечания

1

text должен быть аргументом initialize, чтобы методы можно было использовать для любой строки, а не только для одной жестко заданной строки. @letters не следует инициализировать здесь, поскольку его нужно инициализировать в calculate_frequencies каждый раз, когда вызывается этот метод (и там он не должен быть переменной экземпляра).

2

Для str, calculate_frequencies возвращает

ltr.send(:calculate_frequencies) 
  #=> {"n"=>2, "o"=>7, "w"=>2, "i"=>6, "s"=>3, "t"=>8, "h"=>3, "e"=>6,
  #    "m"=>3, "f"=>2, "r"=>3, "a"=>3, "l"=>3, "u"=>1, "b"=>2, "y"=>1,
  #    "c"=>1, "d"=>1, "g"=>1}

Object # send вызывает private методы, а также методы public или protected.

3

См. Hash # fetch и String # *.

4

Все методы, определенные после вызова ключевого слова private, являются закрытыми, до тех пор, пока не будет найдено ключевое слово public или protected. В качестве альтернативы можно определить один частный метод как private def calculate_frequencies; ... ; end. Также открытый (или защищенный) метод m может быть сделан приватным, выполнив private m.

5

Одним из соглашений Ruby является использование snake-case для имен переменных и методов. Вы не должны следовать этому соглашению, но 99% + Rubyists делают.

6

String # each_char возвращает перечислитель, тогда как String # chars возвращает массив. Последний должен использоваться только тогда, когда нужен массив или он связан с методом Array; в противном случае предпочтительным является each_char, поскольку он не создает ненужный временный массив.

7

См. Перечислитель # with_object .

8

Вместо того, чтобы сопоставлять все, кроме пробелов, вы, вероятно, хотите сопоставлять только буквы. Обратите внимание, как я использовал if здесь, чтобы избежать необходимости в двух утверждениях. См. String # match? . Вместо этого можно написать c =~ /\p{Lower}/ или c[/\p{Lower}/]. \p{Lower} (или [[:lower:]]) соответствует любой строчной букве Unicode, которая обычно предпочтительнее /[a-z]/. Даже в английском тексте можно встретить слова, имеющие буквы с диакритическими знаками, такие как née, Señor, excé и rosé. "é".match? /[a-z]/ #=> false но "é".match? /\p{Lower}/ #=> true. Найдите документ Regexp для \p{Lower} и [[:lower:]].

0 голосов
/ 03 января 2019

Хорошее начало:)

Чтобы сделать метод приватным, поместите его после вызова private в классе:

class foo
  # all methods are public by default
  def something_public
    # …
  end

  private
  # makes all methods after this call private
  def something_internal
    # …
  end
end

В качестве альтернативы, вы можете вызвать private с именем символа метода, который вы хотите сделать private (после того, как он был определен): private :something_internal. В более новых версиях ruby ​​определение метода возвращает имя метода (в виде символа), поэтому вы также можете сделать это:

private def something_internal
  # …
end

, чтобы сделать только один метод приватным.

В ruby ​​«private» означает, что вы не можете вызвать метод с точкой, например, foo.something_internal вызовет NoMethodError, если something_internal - это закрытый метод для foo. Это означает, что для вызова приватного метода вам необходимо находиться в методе того же класса:

class foo
  # …

  def something_public
    if something_internal # method called without a dot
      'the internal check was truth'
    else
      'the internal check was falsey'
    end
  end

  # …
end

Закрытые методы обычно используются для создания помощников для класса, которые не имеют смысла вызывать извне класса, или которые могут вызывать ошибки, если они вызываются не в то время. В ruby ​​вы можете вызвать закрытый метод в любом случае, если вы действительно хотите, используя send: foo.send(:something_internal, 'some', 'arguments'). Но, как правило, вам не нужно этого делать, и вам следует переосмыслить свой код и посмотреть, сможете ли вы его реорганизовать, чтобы не нужно было вызывать send.

Кроме того, по соглашению в ruby ​​имена методов snake_cased и обычно не начинаются с заглавной буквы (хотя язык допускает это).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...