2013-02-22 6 views
2

Как мне подсчитать общее количество символов в массиве строк в Ruby? Предположим, у меня есть следующий:Подсчитать количество символов в массиве строк в Ruby?

array = ['peter' , 'romeo' , 'bananas', 'pijamas'] 

Пытаюсь:

array.each do |counting| 
    puts counting.count "array[]" 
end 

, но я не получаю желаемый результат. Кажется, я считаю что-то отличное от персонажей.

Я искал свойство count, но мне не повезло или нашел хороший источник информации. В принципе, я хотел бы получить выход от общего количества символов в массиве., Ответ

+0

Исходные проблемы связаны с тем фактом, что вы имеете дело с объектом Array, который содержит коллекцию объектов String. В отличие от C и ряда других языков, String является * not * массивом символов. –

+0

Если вы напишете значительное количество Ruby, я настоятельно рекомендую собрать * The Ruby Way * (http://goo.gl/8qa79) и * Eloquent Ruby * (http://goo.gl/oa8lc). Это книги, которые нужно читать в укусах, а не изучать. Прочитайте и перечитайте их. А затем найдите код Ruby для чтения и смакивания. –

ответ

1
a = ['peter' , 'romeo' , 'bananas', 'pijamas'] 

count = 0 
a.each {|s| count += s.length} 
puts count 
+1

Если вы накапливаете значения в каждом цикле, вы можете попытаться сделать это с помощью цикла 'map' /' inject'/'each_with_object'. – oldergod

+0

@oldergod 'each_with_object', вероятно, не будет работать здесь, так как' Numeric 'неизменны. –

+0

@AndrewMarshall Я говорил в общем. Он должен выбрать тот, который больше всего подходит его делу. – oldergod

9

Wing будет работать, но только для развлечения здесь есть несколько альтернатив

['peter' , 'romeo' , 'bananas', 'pijamas'].inject(0) {|c, w| c += w.length } 

или

['peter' , 'romeo' , 'bananas', 'pijamas'].join.length 

Настоящая проблема заключается в том, что string.count - это не тот метод, который вы ищите. (Docs)

+0

Эти примеры гораздо более идиоматичны Ruby, чем пример Wing Leong. –

+0

Собственно, вы можете использовать string.count с другим подходом. Основная проблема заключается в понимании того, что здесь у вас есть объект Array и коллекция объектов String. Это * не * массив символов ala C. –

2

Другой вариант:

['peter' , 'romeo' , 'bananas', 'pijamas'].join('').size 
5

Или ...

a.map(&:size).reduce(:+) # from Andrew: reduce(0, :+) 
+1

'reduce' даже не нуждается в' & 'и может быть просто:' reduce (: +) '. Также обратите внимание, что если массив пуст, это даст 'nil'; измените его на 'reduce (0,: +)', чтобы он возвращал '0' вместо этого. –

2

Интересный результат :)

>> array = [] 
>> 1_000_000.times { array << 'foo' } 
>> Benchmark.bmbm do |x|           
>> x.report('mapreduce') { array.map(&:size).reduce(:+) }  
>> x.report('mapsum') { array.map(&:size).sum }     
>> x.report('inject') { array.inject(0) { |c, w| c += w.length } } 
>> x.report('joinsize') { array.join('').size }     
>> x.report('joinsize2') { array.join.size }      
>> end 

Rehearsal --------------------------------------------- 
mapreduce 0.220000 0.000000 0.220000 ( 0.222946) 
mapsum  0.210000 0.000000 0.210000 ( 0.210070) 
inject  0.150000 0.000000 0.150000 ( 0.158709) 
joinsize 0.120000 0.000000 0.120000 ( 0.116889) 
joinsize2 0.070000 0.000000 0.070000 ( 0.071718) 
------------------------------------ total: 0.770000sec 

       user  system  total  real 
mapreduce 0.220000 0.000000 0.220000 ( 0.228385) 
mapsum  0.210000 0.000000 0.210000 ( 0.207359) 
inject  0.160000 0.000000 0.160000 ( 0.156711) 
joinsize 0.120000 0.000000 0.120000 ( 0.116652) 
joinsize2 0.080000 0.000000 0.080000 ( 0.069612) 

так это выглядит, как array.join.size имеет самое низкое время выполнения

+0

Я только что сделал любопытный чек, чтобы узнать, что работает быстрее всего, учитывая большой набор данных и представил его здесь. вы правы, что на самом деле это связано с преждевременной оптимизацией, но если ее можно оптимизировать менее чем за 5 минут, я скажу, что это так. (я изменил формулировку для вас.) – jvnill

+0

Я соглашусь, что часто умные функциональные решения в Ruby создают слишком много объектов и на самом деле могут быть слишком медленными. (Это проблема с mapreduce.) В $ dayjob мы однажды сократили время выполнения от нескольких дней до нескольких минут, заменив один '.merge' на' .merge! '. – DigitalRoss

+0

В этом конкретном случае нет необходимости спорить. joinsize2 является лучшим как по эффективности, так и по надежности/удобочитаемости/ремонтопригодности. – sawa