Как сопоставить ненулевой индекс каждому символу в строке - PullRequest
0 голосов
/ 08 февраля 2020

У меня есть строка:

alphabet = "AABBBCCCCDDDDDEFGHIJKLMNOPQRSTUVWXYZZZZZZ"

Я хочу перечислять индекс символа при каждом его появлении. Однако для моих целей начальный начальный индекс будет 1 вместо 0. Мне удалось сделать это для одного символа с этой строкой:

list_all_Z = alphabet.chars.each_with_index.select{|indexx,| indexx.eql? "Z" }.map(&:last).map{|get_rid_of_zero,| get_rid_of_zero + 1 }

Который выводит:

print "all the Z's #{list_all_Z}" --> all the Z's [36, 37, 38, 39, 40, 41]

Как выполнить sh ту же задачу, но для каждой буквы в последовательности, не вводя вручную каждый указанный символ c в

indexx.eql?  

Ответы [ 3 ]

7 голосов
/ 08 февраля 2020

Это один из способов сделать это:

alphabet = "AABBBCCCCDDDDDEFGHIJKLMNOPQRSTUVWXYZZZZZZ"

h = alphabet.each_char.
             with_index(1).
             group_by(&:first).
             transform_values { |a| a.map(&:last) }
  #=> {"A"=>[1, 2], "B"=>[3, 4, 5], "C"=>[6, 7, 8, 9],
  #    "D"=>[10, 11, 12, 13, 14], "E"=>[15], "F"=>[16], "G"=>[17],
  #    "H"=>[18], "I"=>[19], "J"=>[20], "K"=>[21], "L"=>[22], "M"=>[23],
  #    "N"=>[24], "O"=>[25], "P"=>[26], "Q"=>[27], "R"=>[28], "S"=>[29],
  #    "T"=>[30], "U"=>[31], "V"=>[32], "W"=>[33], "X"=>[34], "Y"=>[35],
  #    "Z"=>[36, 37, 38, 39, 40, 41]} 

c = 'Z'
puts "All the #{c}'s: #{h[c]}"
All the Z's: [36, 37, 38, 39, 40, 41]

Шаги следующие:

a = alphabet.each_char
  #=> #<Enumerator:"AABBB...ZZZZZZ":each_char> 
b = a.with_index(1)
  #=> #<Enumerator: #<Enumerator: "AABBB...ZZZZZZ":each_char>:with_index(1)> 
c = b.group_by(&:first)
  #=> {"A"=>[["A", 1], ["A", 2]],
  #    "B"=>[["B", 3], ["B", 4], ["B", 5]],
  #    ...
  #    "Z"=>[["Z", 36], ["Z", 37], ["Z", 38], ["Z", 39], ["Z", 40],
  #          ["Z", 41]]}

b.group_by(&:first) более или менее сокращенно для:

c = b.group_by { |c,i| c }

Наконец:

c.transform_values { |a| a.map(&:last) }
  #=> <as above>

Примечание:

a.next #=> "A"
a.next #=> "A"
a.next #=> "A"
a.next #=> "B"
... 

и

b.next #=> ["A", 1] 
b.next #=> ["A", 2]
b.next #=> ["B", 3] 
b.next #=> ["B", 4] 
...

Элементы, сгенерированные перечислителем b, передаются в Блок group_by, { |c,i| c } и переменные блока присваиваются их значениям. Например:

b.rewind
c, i = b.next #=> ["A", 1] 
c             #=> "A" 
i             #=> 1 

См. Enumerator # with_index , Enumerable # group_by и Hash # transform_values ​​, Enumerator # next и Перечислитель # перемотка .

1 голос
/ 08 февраля 2020
count_all =
  alphabet.
  chars.
  each.
  with_index(1).                   # start with 1
  with_object({}) do |(c, i), acc| # collect
    (acc[c] ||= []) << i
  end

Приведенное выше будет собирать га sh, отображая символы на их индексы на основе 1.

Аккумулятор может быть умнее; три последние строки могут выглядеть так:

  with_object(Hash.new { |h, k| h[k] = [] }) do |(c, i), acc|
    acc[c] << i
  end
0 голосов
/ 09 февраля 2020

Мне нравится быть простым, чтобы мой мозг справился с этим. Я бы сделал это:

str = "AABBBCCCCDDDDDEFGHIJKLMNOPQRSTUVWXYZZZZZZ"

idx = Hash.new { |h, k| h[k] = [] }
str.chars
  .each_with_index { |c, i|
    idx[c] << 1 + i
  }

Что приводит к:

idx
# => {"A"=>[1, 2],
#     "B"=>[3, 4, 5],
#     "C"=>[6, 7, 8, 9],
#     "D"=>[10, 11, 12, 13, 14],
#     "E"=>[15],
#     "F"=>[16],
#     "G"=>[17],
#     "H"=>[18],
#     "I"=>[19],
#     "J"=>[20],
#     "K"=>[21],
#     "L"=>[22],
#     "M"=>[23],
#     "N"=>[24],
#     "O"=>[25],
#     "P"=>[26],
#     "Q"=>[27],
#     "R"=>[28],
#     "S"=>[29],
#     "T"=>[30],
#     "U"=>[31],
#     "V"=>[32],
#     "W"=>[33],
#     "X"=>[34],
#     "Y"=>[35],
#     "Z"=>[36, 37, 38, 39, 40, 41]}

В качестве альтернативы это может быть записано с использованием each.with_index(1) вместо each_with_index и без необходимости присваивать индекс + 1 каждый раз:

str.chars
  .each.with_index(1) { |c, i|
    idx[c] << i
  }

, что приводит к тому же ha sh, или:

idx = str.chars
  .each_with_object(Hash.new { |h, k| h[k] = [] })
  .with_index(1) { |(c, h), i|
    h[c] << i
  }

, который перемещает определение объекта-накопителя в инициализацию each_with_object. Я думаю, что это немного более визуально шумно, но YMMV.

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