【问题标题】:Can't get updated values in array after using .map method使用 .map 方法后无法获取数组中的更新值
【发布时间】:2018-01-27 20:46:14
【问题描述】:

我需要实现一个这样的方法:

# do_magic("abcd") # "Aaaa-Bbb-Cc-D"
# do_magic("a")    # "A"
# do_magic("ab")   # "Aa-B"
# do_magic("teSt") # "Tttt-Eee-Ss-T"

我的决定是将一个字符串转换为一个数组,遍历这个数组并保存结果。代码在块内正常工作,但我无法使用此解决方案获取具有更新值的数组,它返回相同的字符串除以破折号(例如,使用“.map”或“3-2”时的“t-e-S-t” -1-0" 当使用 ".map!" 时):

def do_magic(str)
  letters = str.split ''
  counter = letters.length
  while counter > 0
    letters.map! do |letter|
      (letter * counter).capitalize
      counter -= 1
    end
  end
  puts letters.join('-')
end

错在哪里?

【问题讨论】:

  • while 循环毫无意义且具有误导性。

标签: arrays ruby string


【解决方案1】:

你离得很近。当您有一个块 (letters.map!) 时,该块的返回是最后评估的语句。在这种情况下,counter -= 1 被映射到 letters

试试

l = (letter * counter).capitalize
counter -= 1
l 

【讨论】:

  • 我的想法完全正确 - do_magic("sdfsdf") 返回 "5-4-3-2-1-0"
【解决方案2】:

您可以使用each_with_index 尝试类似的操作

def do_magic(str)
    letters = str.split("")
    length = letters.length
    new_letters = []
    letters.each_with_index do |letter, i|
        new_letters << (letter * (length - i)).capitalize
    end
    new_letters.join("-")
end

使用 map_with_index 等效于 each_with_index.map

def do_magic(str)
    letters = str.split("")
    length = letters.length
    letters.each_with_index.map { |letter, i| 
       (letter * (length - i)).capitalize 
    }.join("-")
end

【讨论】:

  • 你可以用chars代替split("")
【解决方案3】:

我建议如下。

def do_magic(letters)
  length = letters.size
  letters.downcase.each_char.with_index.with_object([]) { |(letter, i), new_letters|
    new_letters << (letter * (length - i)).capitalize }.join
end

do_magic 'teSt'
  # => "TtttEeeSsT"

让我们完成这些步骤。

letters = 'teSt'

length = letters.size
  #=> 4
str = letters.downcase
  #=> "test"
enum0 = str.each_char
  #=> #<Enumerator: "test":each_char>
enum1 = enum0.with_index
  #=> #<Enumerator: #<Enumerator: "test":each_char>:with_index>
enum2 = enum1.with_object([])
  #=> #<Enumerator: #<Enumerator: #<Enumerator: "test":each_char>:
  #     with_index>:with_object([])>

仔细检查创建枚举器enum0enum1enum2 的返回值。后两者可以被认为是复合枚举数

第一个元素由enum2enum2.next 的值)生成,块变量使用消歧(又名分解)赋值。 p>

(letter, i), new_letters = enum2.next
  #=> [["t", 0], []]
letter
  #=> "t"
i #=> 0
new_letters
  #=> []

然后执行块计算。

m = letter * (length - i)
  #=> "tttt"
n = m.capitalize
  #=> "Tttt"
new_letters << n
  #=> ["Tttt"]

下一个元素由enum2生成,传递给block并进行block计算。

(letter, i), new_letters = enum2.next
  #=> [["e", 1], ["Tttt"]]
letter
  #=> "e"
i #=> 1
new_letters
  #=> ["Tttt"]

注意new_letters 是如何更新的。分块计算如下。

m = letter * (length - i)
  #=> "eee"
n = m.capitalize
  #=> "Eee"
new_letters << n
  #=> ["Tttt", "Eee"]

enum2 的最后两个元素生成后,我们有

new_letters
  #=> ["Tttt", "Eee", "Se", "T"]

最后一步是将new_letters的元素组合成一个字符串。

new_letters.join
  #=> "TtttEeeSeT"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-07
    • 2011-05-30
    • 1970-01-01
    • 1970-01-01
    • 2016-07-23
    相关资源
    最近更新 更多