Ruby 如何将非零索引映射到字符串中的每个字符

Ruby 如何将非零索引映射到字符串中的每个字符,ruby,Ruby,我有一个字符串: 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_

我有一个字符串:

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]
除了序列中的每个字母,我如何在不手动输入每个特定字符的情况下完成相同的任务

indexx.eql?  

这是一种方法:

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]]}
最后:

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

枚举器b生成的元素被传递给group|U by的块{| c,i | c},块变量被分配给它们的值。例如:

b.rewind
c, i = b.next #=> ["A", 1] 
c             #=> "A" 
i             #=> 1 
请参阅、和。

全部计数= 字母表 查斯。 每个 使用_index1。从1开始 用{}do{c,i,acc{collect
acc[c]| |=[]我喜欢保持简单,这样我的大脑就能处理它。我会这样做:

str = "AABBBCCCCDDDDDEFGHIJKLMNOPQRSTUVWXYZZZZZZ"

idx = Hash.new { |h, k| h[k] = [] }
str.chars
  .each_with_index { |c, i|
    idx[c] << 1 + i
  }
或者,可以使用each.with_index1而不是each.with_index1写入,并且每次不必指定索引+1:

str.chars
  .each.with_index(1) { |c, i|
    idx[c] << i
  }
导致相同的哈希,或:

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

这会将累积对象的定义移动到带有\u对象初始化的每个\u中。我认为它在视觉上有点嘈杂,但YMMV。

一个小而短暂的建议:每个字符。@CarySwoveland我诚实地尝试避免语法上的甜点,即使它不会节省击键:chars.each..size=>11;每个字符..大小=>10。。。每个字符都避免了创建临时数组。可选的.group_by&:first.transform_values{| a | a.map&:last}是.group_by&:shift.transform_values&:PLANT。@3limin4t0r,在这种情况下,first比shift更精确,PLANT不正确。[A,1],[A,2].[A,0,A,1].[A,0,A,1].@Thang,你忘了移位是破坏性的。它是[[1],[2]]。扁平=>[1,2]。@CarySwoveland,我现在看到了,应该对它进行完整的测试,而不仅仅是替换件扁平化。抱歉@3limin4t0r
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]}
str.chars
  .each.with_index(1) { |c, i|
    idx[c] << i
  }
idx = str.chars
  .each_with_object(Hash.new { |h, k| h[k] = [] })
  .with_index(1) { |(c, h), i|
    h[c] << i
  }