【问题标题】:create comma separated string in the First element of an array Ruby在数组Ruby的第一个元素中创建逗号分隔的字符串
【发布时间】:2019-09-20 16:02:21
【问题描述】:

所以这可能看起来很奇怪,我已经做了很多谷歌搜索,但是,我并不是真正的程序员,(系统操作员)并试图弄清楚如何以所需的格式将数据传递给 AWS API,这似乎有点奇怪。

因此,在 AWS 中使用资源时,我需要传递作为键和值的标签。键是一个字符串。该值是一个逗号分隔的字符串,位于数组的第一个元素中。所以用 Ruby 术语来说,看起来像这样。

{env => ["stage,qa,dev"]} 

而不是

{env => ["stage","qa","dev"]}

无可否认,我是被创造出来的。不是一个非常漂亮的小应用程序,它允许我在 aws 中的目标实例上运行 ssm 文档。

我可以使用我创建的这个类将字符串放入数组元素中

class Tags

  attr_accessor :tags

  def initialize
    @tags    = {"env" => nil ,"os" => nil ,"group" => nil }
  end

  def set_values()
    puts "please enter value/s for the following keys, using spaces or commas for multiple values"
    @tags.each { |key,value|
    print "enter #{key} value/s: "
    @tags[key] = [gets.strip.chomp]
    @tags[key] = Validate.multi_value(tags[key])
    }
  end

end

然后我调用这个 Validate.multi_value 并传入创建的数组,但它会返回一个包含我的字符串值的数组。

class Validate
  def self.multi_value(value)
      if value.any?{ |sub_string| sub_string.include?(",") || sub_string.include?(" ") }
         value = value[0].split(/[,\s]+/)
       return value
      else
       return value
     end

    end

end

使用 pry,我看到它得到例如 ["stage dev qa"] 然后 if 语句确实有效,然后它吐出 ["stage","dev","qa"]

我需要它来输出["stage,dev,qa"],但为了我的一生,我无法让它工作。

我希望这很清楚。

如果您有任何建议,我将不胜感激。

我在 ruby​​ 方面的经验并不丰富,可能是我错过的类方法。

【问题讨论】:

  • 附带说明,请参阅Ruby style guide 了解多行块语法,@tags.each { |key,value| 应为@tags.each do |key,value| 并在最后一行以end 结尾。

标签: ruby amazon-web-services


【解决方案1】:

如果您的数组总是以["stage dev qa"] 格式通过,那么首先我们需要将一个字符串拆分为我们想要的部分:

arr = ["stage dev qa"]
arr.split(' ')
=> ["stage", "dev", "qa"]

然后我们需要用逗号将它们连接起来:

arr.split(' ').join(',')
=> "stage,dev,qa"

最后我们需要将它包装在一个数组中:

[arr.first.split(' ').join(',')]
=> ["stage,dev,qa"]

大家一起:

def transform_array(arr)
  [arr.first.split(' ').join(',')]
end

transform_array(['stage dev qa'])
=> ['stage,dev,qa']

更多信息:How do I convert an array of strings into a comma-separated string?

【讨论】:

  • 非常感谢,非常优雅。我有点得出这样的结论,但非常冗长。 def self.multi_value(value) if value.any?{ |sub_string| sub_string.include?(",") || sub_string.include?(" ") } result = [] value = value[0].split(/[,\s]+/) value = value.join(",") result[0] = value return result else return value end end
  • 不客气,是的,我们几乎都在同一条轨道上 :)
  • 为什么要在空格上分割字符串,然后用逗号重新连接,而不是仅仅将空格转换为逗号?
【解决方案2】:

当一个简单的方法可以做时,我认为在这里创建一个类是没有意义的。

def set_values
  ["env", "os", "group"].map do |tag|
    puts "Please enter values for #{tag}, using spaces or commas"
    print "to separate multiple values: "
    gets.strip.gsub(/[ ,]+/, ',')
  end
end

假设,当被询问时,用户输入 "stage dev,qa" (for"env"), "OS X" (for"OS") and "Hell's Angels""group"。那么:

set_values
  #=> ["stage,dev,qa", "OS,X", "Hell's,Angels"]

如果我怀疑,您只想将"env" 的空格转换为逗号,而不是"os""group",请写:

def set_values 
  puts "Please enter values for env, using spaces or commas"
  print "to separate multiple values: "
   [gets.strip.gsub(/[ ,]+/, ',')] +
   ["os", "group"].map do |tag|
     print "Please enter value for #{tag}: "
     gets.strip
   end
end

set_values
  #=> ["stage,dev,ga", "OS X", "Hell's Angels"] 

请参阅Array#mapString#gsubArray#+

gets.strip.gsub(/[ ,]+/, ',') 只是链接两个操作s = gets.strips.gsub(/[ ,]+/, ',')。链接在 Ruby 中很常见。

gsub 使用的正则表达式为“匹配一个或多个空格或逗号”,[ ,] 是一个字符类,要求匹配该类中的一个字符,@ 987654340@ 表示要匹配这些空格或逗号中的一个或多个。如果字符串是"a , b,, c",将会有两个匹配项," , "",, "gsub 会将两者都转换为单个逗号。

使用print 而不是puts 会在提示符所在的同一行显示用户的输入,紧跟在": " 之后,而不是在下一行。这当然是纯粹的风格。

通常人们会写gets.chomp 而不是gets.strip。都删除了字符串末尾的换行符和其他空格,strip 也删除了字符串开头的所有空格。 strip 在这种情况下可能是最好的。

【讨论】:

    【解决方案3】:

    您对此有何看法?所有内容都在 Validates 方法中得到处理。我不知道你是否想删除重复的值,但是,以防万一,所以一个

    "this    string,, has too  many,,, , spaces"
    

    会变成

    "this,string,has,too,many,spaces"
    

    而不是

    "this,,,,string,,,has,too,,many,,,,,,spaces"
    

    这是代码

    class Tags
      attr_accessor :tags
    
      # initializes the class (no change)
      #
      def initialize
        @tags = {"env" => nil ,"os" => nil ,"group" => nil }
      end
    
      # request and assign the values <- SOME CHANGES
      #
      def set_values
        puts "please enter value/s for the following keys, using spaces or commas for multiple values"
        @tags.each do |key,value|
          print "enter #{key} value/s: "
          @tags[key] = Validate.multi_value( gets )
        end
      end
    end
    
    class Validate
      # Sets the array
      #
      def self.multi_value(value)
        # Remove leading spaces, then remove special chars,
        # replace all spaces with commas, then remove repetitions
        #
        [ value.strip.delete("\n","\r","\t","\rn").gsub(" ", ",").squeeze(",") ]
      end
    end
    
    

    已编辑,感谢 lacostenycoder

    【讨论】:

    • .remove 没有在核心 Ruby 的 String 类中定义,而是由 Rails 的 active_support 提供。但是,您可以使用.delete,它位于core Ruby
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-05
    • 1970-01-01
    • 2011-06-20
    • 1970-01-01
    • 2020-11-13
    • 2012-05-19
    相关资源
    最近更新 更多