Подтвердить что ты не робот

Как преобразовать массив строк в массив символов?

Я хочу преобразовать элементы массива строк ниже в символы и вывести их

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

посмотрите, что я делаю:

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

Нет успеха. Что я делаю неправильно?

4b9b3361

Ответ 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 уже дал правильный ответ.

Дополнительное примечание:

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 лучше всего работает в большинстве случаев, когда в массиве есть еще несколько элементов, но если это очень маленький массив, метод сбора работает немного быстрее.

Я публикую здесь код и результаты, это мой настоящий первый тест, поэтому, если у меня что-то получится, некоторые отзывы будут оценены. Я сделал это как на 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

Или может быть сделано следующим образом:

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