Количество, размер, длина...слишком много вариантов в Ruby?
Я не могу найти окончательного ответа на этот вопрос, и я хочу убедиться, что я понимаю это до "n-го уровня": -)
a = { "a" => "Hello", "b" => "World" }
a.count # 2
a.size # 2
a.length # 2
a = [ 10, 20 ]
a.count # 2
a.size # 2
a.length # 2
Так что же использовать? Если я хочу знать, имеет ли a более одного элемента, то это не имеет значения, но я хочу убедиться, что понимаю реальную разницу. Это относится и к массивам. Я получаю те же результаты.
кроме того, я понимаю, что count/size/length имеют разные значения с ActiveRecord. Я в основном интересовался чисто Ruby (1.92) прямо сейчас, но если кто-то хочет вмешаться в разницу, которую делает AR, это также будет оценено.
спасибо!
6 ответов:
для массивов и хэшей
sizeпсевдонимlength. Они являются синонимами и делают точно то же самое.
countявляется более универсальным - он может принимать элемент или предикат и считать только те элементы, которые соответствуют.> [1,2,3].count{|x| x > 2 } => 1
в том случае, когда вы не укажите параметр для подсчета он имеет в основном тот же эффект, что и длина вызова. Там может быть разница в производительности хотя.
мы можем видеть из исходный код для массива что они делают почти то же самое. Вот код C для реализации
array.length:static VALUE rb_ary_length(VALUE ary) { long len = RARRAY_LEN(ary); return LONG2NUM(len); }а вот и соответствующая часть из реализации
array.count:static VALUE rb_ary_count(int argc, VALUE *argv, VALUE ary) { long n = 0; if (argc == 0) { VALUE *p, *pend; if (!rb_block_given_p()) return LONG2NUM(RARRAY_LEN(ary)); // etc.. } }код
array.countделает несколько дополнительных проверок, но в конце концов вызывает тот же самый код:LONG2NUM(RARRAY_LEN(ary)).хэши (исходный код) С другой стороны не кажется реализуйте свою собственную оптимизированную версию
countтак что реализация отEnumerable(исходный код), которая перебирает все элементы, и подсчитывает их по одному.в общем я бы посоветовал использовать
length(или его псевдонимsize), а неcountесли вы хотите знать, сколько элементов в целом.
Что касается ActiveRecord, с другой стороны, там are важные различия. проверьте это сообщение:
существует важное различие для приложений, которые используют подключения к базе данных.
когда вы используете много ORMs (ActiveRecord, DataMapper и т. д.) общее понимание таково .размер будет генерировать запрос, который запрашивает все элементы из базы данных ('select * from mytable'), а затем дать вам количество элементов в результате, тогда как .count будет генерировать один запрос ('select count (*) from mytable'), который значительно быстрее.
потому что эти Ормы настолько распространены, что я следую принципу наименьшего удивления. Вообще если у меня что-то в памяти уже есть, то я пользуюсь .размер, и если мой код будет генерировать запрос к базе данных (или внешней службе через API) я использую .рассчитывать.
в большинстве случаев (например,массив или строка)
sizeЭто псевдоним наlength.
countобычно наступает от перечисли и может принимать дополнительный блок предикатов. Таким образомenumerable.count {cond}- это [примерно](enumerable.select {cond}).length-- он может, конечно, обойти промежуточную структуру, поскольку ему просто нужно количество совпадающих предикатов.примечание: Я не уверен, если
countсил оценка перечисление, если блок не указан или если он замыкается наlengthесли это возможно.редактировать (и благодаря ответу Марка!):
countбез блока (по крайней мере для массивов) не силу оценки. Я полагаю, что без формального поведения он "открыт" для других реализаций, если принуждение оценки без предиката когда-либо даже действительно имеет смысл.
Я нашел хороший answare в http://blog.hasmanythrough.com/2008/2/27/count-length-size
в ActiveRecord есть несколько способов узнать, сколько записей в ассоциации, и есть некоторые тонкие различия в том, как они работают.
пост.комментарии.count-определяет количество элементов с помощью SQL Подсчет запросов. Вы также можете указать условия для подсчета только подмножества связанные элементы (например: условия => {:имя автора>= "подшучивать.)}" Если вы настроили кэш счетчиков в ассоциации, #count возвращает это кэшированное значение вместо выполнения нового запроса.
пост.комментарии.длина - это всегда загружает содержимое ассоциация в память, затем возвращает количество загруженных элементов. Обратите внимание, что это не приведет к принудительному обновлению, если связь была ранее загруженные, а затем новые комментарии были созданы через другой способ (например, комментарий.создавать.(..) вместо того должность.комментарии.создавать.(..)).
пост.комментарии.размер - это работает как комбинация двух предыдущих опции. Если коллекция уже была загружена, она вернет ее длина так же, как вызов #length. Если он еще не был загружен, это например, вызов #count.
также у меня есть личный опыт:
<%= h(params.size.to_s) %> # works_like_that ! <%= h(params.count.to_s) %> # does_not_work_like_that !
у нас есть несколько способов, чтобы узнать, сколько элементов в массиве, как
.length,.countи.size. Однако, лучше использоватьarray.size, а неarray.count. Потому что.sizeлучше в производительности.
добавление больше, чтобы Марк Байерс ответить. В Ruby метод
array.size- это псевдоним для массив длина# метод. Нет никакой технической разницы в использовании этих двух методов. Возможно, вы также не увидите никакой разницы в производительности. Тем не менее,array.countтакже делает ту же работу, но с некоторыми дополнительными функциями массив#countон может быть использован, чтобы получить полное отсутствие элементов на основе некоторых условий. Счет можно назвать в три способы:
массив#count # возвращает количество элементов в массиве
массив#count n # возвращает количество элементов, имеющих значение N в массиве
Array#count {|i / i.even?} возвращает счетчик на основе условия, вызванного на каждом элементе массива
array = [1,2,3,4,5,6,7,4,3,2,4,5,6,7,1,2,4] array.size # => 17 array.length # => 17 array.count # => 17здесь все три метода выполняют одну и ту же работу. Однако вот где то
countстановится интересно.допустим, я хочу найти сколько элементов массива содержит массив со значением 2
array.count 2 # => 3массив имеет в общей сложности три элемента со значением 2.
теперь я хочу найти все элементы массива больше, чем 4
array.count{|i| i > 4} # =>6массив имеет всего 6 элементов, которые > чем 4.
Я надеюсь, что это дает некоторую информацию о
countметод.
Comments