【问题标题】:How to convert a array of strings to an array of symbols?如何将字符串数组转换为符号数组?
【发布时间】:2013-05-06 08:30:24
【问题描述】:

我想将下面字符串数组的元素转换为符号,并输出

strings = ["HTML", "CSS", "JavaScript", "Python", "Ruby"]

看看我在做什么:

strings.each { |x| puts x.to_sym }

没有成功。我做错了什么?

【问题讨论】:

  • @Abe:那是哈希键。这是针对数组元素的。
  • @icktofay 我明白了,但转换它们很容易,对吧?
  • @Abe 这并不意味着它是重复的......而且,不是真的。你知道鲁比吗?
  • @Abe:也许吧,但如果你刚开始尝试用数组来做,你会有一个更清晰的答案。

标签: ruby


【解决方案1】:

使用map 而不是each

>> strings.map { |x| x.to_sym }
=> [:HTML, :CSS, :JavaScript, :Python, :Ruby]

对于 Ruby 1.8.7 及更高版本或包含 ActiveSupport,您可以使用以下语法:

>> strings.map &:to_sym
=> [:HTML, :CSS, :JavaScript, :Python, :Ruby]

您的each 方法似乎不起作用的原因是使用符号调用puts 会输出符号的字符串表示形式(即,没有:)。此外,您只是循环并输出内容;你实际上并没有构建一个新数组。

【讨论】:

    【解决方案2】:

    清洁单线:

    %w(HTML CSS JavaScript Python Ruby).map(&:to_sym)
    

    & 告诉参数应该被视为一个块,即构建数组并将to_sym 应用于每个元素。

    【讨论】:

    • 你的答案是最干净的,我也对它进行了基准测试并检查了它在不同类型阵列上的性能。我不确定是根据你的答案给出一个新的答案还是直接编辑这个更好。
    【解决方案3】:

    我会做类似的事情

    strings.map! &:to_sym
    

    【讨论】:

      【解决方案4】:

      icktoofay already gave the correct answer.

      关于补充说明:有

      strings.map { |x| x.to_sym }
      

      你得到一个新数组,原来的数组没有改变。

      要使用它,您可以将它分配给另一个变量:

      string2 = strings.map { |x| x.to_sym }
      

      如果要修改字符串,可以使用map!

      strings.map! { |x| x.to_sym }
      

      【讨论】:

        【解决方案5】:

        @icktoofay 有正确答案,但只是为了帮助您更好地理解each 方法,下面是使用each 做同样事情的方法:

        strings = ["HTML", "CSS", "JavaScript", "Python", "Ruby"]
        symbols = [] # an empty array to hold our symbols
        strings.each { |s| symbols << s.to_sym }
        

        【讨论】:

          【解决方案6】:

          @cb24 的回答通常是最合适的,我想将该解决方案与另一个解决方案进行比较

          strings.collect {|x| x.to_sym }
          

          我做了一些基准测试,@cb24 的答案在大多数情况下效果最好,当数组中有更多元素时,但如果它恰好是一个非常小的数组,collect 方法的工作速度会快一些。

          我在这里发布代码和结果,这是我真正的第一个基准测试,所以如果我有什么错误,我们将不胜感激。我在 String -> Symbol 和 Symbol -> String

          上都这样做了
          n = 1000000 
          
          a = [:a,:b,:c,:d,:e,:f,:g,:h,:i].freeze #A "long" array of symbols
          
          Benchmark.bm do |x|
            x.report { n.times { a.map(&:to_s)} }
            x.report { n.times { a.collect{|x| x.to_s}} }
          end  
          
                 user     system      total        real
             2.040000   0.010000   2.050000 (  2.056784)
             2.100000   0.010000   2.110000 (  2.118546)
          
          
          b = [:a, :b].freeze  #Small array
          
          Benchmark.bm do |x|
            x.report { n.times { b.map(&:to_s)} }
            x.report { n.times { b.collect{|x| x.to_s}} }
          end  
          
          
                 user     system      total        real
             0.610000   0.000000   0.610000 (  0.622231)
             0.530000   0.010000   0.540000 (  0.536087)
          
          
          
          w = %w(a b).freeze  #Again, a small array, now of Strings
          Benchmark.bm do |x|
            x.report { n.times { w.map(&:to_sym)} }
            x.report { n.times { w.collect{|x| x.to_sym}} }
          end 
          
                 user     system      total        real
             0.510000   0.000000   0.510000 (  0.519337)
             0.440000   0.010000   0.450000 (  0.447990)
          
          
          
          y = %w(a b c d e f g h i j k l m n o p q).freeze #And a pretty long one
          Benchmark.bm do |x|
            x.report { n.times { y.map(&:to_sym)} }
            x.report { n.times { y.collect{|x| x.to_sym}} }
          end 
          
                 user     system      total        real
             2.870000   0.030000   2.900000 (  2.928830)
             3.240000   0.030000   3.270000 (  3.371295)
          

          拐点我没有计算,但很有趣,我在某处读到一些改进是用短数组进行的,因为它们中的大多数只是几个元素长。

          【讨论】:

            【解决方案7】:

            如果您想走 gem 路线,finishing_moves 有一个 Array#to_sym_strict 方法可以满足您的需求:

            strings = ["HTML", "CSS", "JavaScript", "Python", "Ruby"]
            strings.to_sym_strict
            # => [:HTML, :CSS, :JavaScript, :Python, :Ruby]
            

            还有一个#to_sym_loose 来处理混合类型的数组:

            strings = ["HTML", "CSS", "JavaScript", "Python", "Ruby", 1, /a regex/, {a: :hash}]
            strings.to_sym_loose
            # => [:HTML, :CSS, :JavaScript, :Python, :Ruby, 1, /a regex/, {a: :hash}]
            # no exceptions thrown
            

            【讨论】:

              【解决方案8】:

              或者可以如下进行:

              strings.each do |s|  
              symbols.push(s.to_sym)
              

              【讨论】:

                【解决方案9】:

                为了完整起见,您还可以使用至少从 Ruby 2.0.0 开始的 %i 字符串字面量以使用符号数组开始。

                %i[HTML CSS JavaScript Python Ruby]
                # => [:HTML, :CSS, :JavaScript, :Python, :Ruby]
                

                【讨论】:

                  猜你喜欢
                  • 2021-12-13
                  • 1970-01-01
                  • 1970-01-01
                  • 2017-11-27
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2021-11-20
                  相关资源
                  最近更新 更多