如何将字符串数组转换为符号数组?

时间:2013-05-11 23:58:07

标签: ruby

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

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

看看我在做什么:

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

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

9 个答案:

答案 0 :(得分:45)

使用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会输出符号的字符串表示形式(即没有:)。另外,你只是循环并输出东西;你实际上并没有构建一个新阵列。

答案 1 :(得分:21)

清洁单行:

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

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

答案 2 :(得分:9)

我做的事情

strings.map! &:to_sym

答案 3 :(得分: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 }

答案 4 :(得分:2)

@icktoofay有正确答案,但为了帮助您更好地理解each方法,以下是使用each执行相同操作的方法:

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

答案 5 :(得分:1)

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

strings.collect {|x| x.to_sym }

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

我在这里发布了代码和结果,这是我真正的第一个基准,所以如果我出错了,一​​些反馈将会受到赞赏。我在两个字符串上做了 - &gt;符号和符号 - &gt;串

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)

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

答案 6 :(得分:0)

或者可以按如下方式完成:

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

答案 7 :(得分:0)

如果您想走宝石路线,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 :(得分:0)

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

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