如果满足条件,则在字符串插值中添加子字符串

时间:2016-03-03 01:20:40

标签: ruby literals

我得到一个数组,并且必须根据元素加入与每个元素对应的某些项目:

  1. 如果元素是字符串string或格式为[string]的数组,请在输出中包含string
  2. 如果元素是[string1, string2]形式的数组,则如果"--string1"长于一个字符,则在输出中包含string1,否则为"-string1"。然后在结果中加入"string2"
  3. 因此["cat",["dog","fish"],["cow"]]会输出"cat --dog fish cow"[["a","bat"],"mouse"]会输出"-a bat mouse"

    其他人写了以下代码:

    def args_to_string args
      args.map{ |i,j| j ? "#{?-if i[1]}-#{i} #{j}" : i}*" "
    end
    
    • 我知道最后的splat *意味着只需接收一个参数就可以阻止该块,并且在这种情况下为nil
    • 然后是一个三元if-then语句。下一行:

      "#{?-if i[1]}-#{i} #{j}"
      
      如果i有第二个字符,

      包含一个额外的连字符。

    • #{}中的大括号之间可以有什么关系?如果满足条件,我如何包含特定字符串?
    • 在上面的例子中,为什么连字符前面有一个问号?

2 个答案:

答案 0 :(得分:2)

让我们试着逐步完成计算。

args = ["cat", ["dog","fish"], ["cow"]]

操作线是

args.map { |i,j| j ? "#{ ?- if i[1] }-#{ i } #{ j }" : i } * " "

让我们打破它。

enum = args.map
  #=> #<Enumerator: ["cat", ["dog", "fish"], ["cow"]]:map> 

我们可以将这个枚举器转换为数组,看看它将传递给块的三个元素。

enum.to_a
  #=> ["cat", ["dog", "fish"], ["cow"]] 

enum的第一个元素传递给块,并使用并行(或多个)赋值确定块变量的值:

i,j = enum.next
  #=> "cat"
i #=> "cat"
j #=> nil

str = "#{ ?- if i[1] }-#{ i } #{ j }"
  #=> "#{ "-" if "a" }-cat "   Note "#{ nil }" => "" 
  #=> "--cat "    
j ? str : i
  #=> nil ? "--cat " : "cat"
  #=> "cat"

因此"cat"映射到"cat"

注意i[1] => nil i是一个单字符的字符串,虽然在示例中没有使用,但很重要。接下来,将enum的第二个元素传递给块。

i,j = enum.next
  #=> ["dog", "fish"] 
i #=> "dog" 
j #=> #=> "fish" 
str = "#{ ?- if i[1] }-#{ i } #{ j }"
  #=> "#{ "-" if "o" }-dog fish"
  #=> "--dog fish" 
j ? str : i
  #=> "fish" ? "--dog fish" : "dog"
  #=> "--dog fish"
因此,

["dog", "fish"]已映射到"--dog fish"

i,j = enum.next
  #=> ["cow"] 
i #=> "cow" 
j #=> nil 
str = "#{ ? - if i[1] }-#{ i } #{ j }"
  #=> "#{ "-" if "o" }-cow "
  #=> "--cow " 
j ? str : i
  #=> nil ? "--cow " : "cow 
  #=> "cow" 

"cow"已映射到"cow"

enum.next
  #=>StopIteration: iteration reached an end

所以我们完成了map。我已经展示了

a = enum.each { |i,j| j ? "#{?-if i[1]}-#{i} #{j}" : i}
  #=> ["cat", "--dog fish", "cow"]

是怎样的

args.map{ |i,j| j ? "#{?-if i[1]}-#{i} #{j}" : i}
  #=> ["cat", "--dog fish", "cow"]

已实施。最后一步是

a * " "
  #=> a.join(" ")
  #=> "cat --dog fish cow"

因为Array#*“相当于ary.join(str)”。

答案 1 :(得分:1)

  

末尾的splat *意味着块只需接收一个参数

即可

没有。带有字符串参数的Array#*join相同。

  

如果满足条件,如何包含特定字符串?

你这样做:

"#{"foo" if some_contition}"

它实际上在代码中用作#{?-if i[1]}

  

为什么连字符前面有问号?

保存字符。它是单字符串的文字。 ?-相当于"-"

简而言之,请阅读手册。