很简单的一个问题,但其实了解後蛮好玩的。
length : 长度。
size : 尺寸。
count : 计数。
size
&length
。
在阵列与Hash这种长条状的资料上,size
与length
基本上一样,也可说是size
是length
的别名,阵列与Hash在记忆体中,就是一条长条状的储存方式,所以长度本就比尺寸来形容更恰当。
length比size要多打2个字母啦。
2.7.3 :009 > [1, 2, 3, 4].size
=> 4
2.7.3 :010 > [1, 2, 3, 4].length
=> 4
或者该说,记忆体型态上如果是这种长条型的,length
与size
没有差别,都是能了解长度
的同名方法而已了。
例如Integer
这个型态就没有length
,虽然一般size
都是8。
2.7.3 :001 > 8.size
=> 8
2.7.3 :002 > 8.length
Traceback (most recent call last):
(irb):2:in `<main>': undefined method `length' for 8:Integer (NoMethodError)
count
。
length
、size
、count
都是计数方法,但count
在执行上不是只有计算长度或尺寸,本身也是迭代枚举产生器,可以对每一个元素作纪录或操作,没有给予条件的话回传有几个元素。所以在Ruby
单纯算长度等不要用count
,会稍微慢一点点。
2.7.3 :018 > [1, 2, 3, 4].count
=> 4
2.7.3 :019 > [1, 2, 3, 4].count(3)
=> 1
2.7.3 :020 > [1, 2, 3, 4].count {|num| num > 2}
=> 2
某些Class就不能直接以count
计算长度(或没有此方法),只有纪录或查询功能。
2.7.3 :023 > 65.count
Traceback (most recent call last):
(irb):23:in <main>': undefined method `count' for 65:Integer (NoMethodError)
2.7.3 :024 > "abc efg abc".count
count: wrong number of arguments (given 0, expected 1+) (ArgumentError)
2.7.3 :025 > "abc efg abc".count("a")
=> 2
2.7.3 :026 > "abc efg abc".count("ac")
=> 4
2.7.3 :027 > "abc efg abc".count("efg")
=> 3
想找符合efg
这样连续的吗? 请记得改用Regexp
。
2.7.3 :029 > "abc efg abc".match(/efg/)
=> #<MatchData "efg">
在Rails中,这三者被讨论的部分在ActiveRecord
这个部分。
length
与count
本质上不一样的方法,在有不一样用途时就该用不同的方法。
length
。
当如果已经load
过所有资料,单纯查length
的话,就该用length
,而不是count
,以避免再对资料库再一次进行query
。
2.7.3 :001 > user = User.first
User Load (1.1ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT $1 [["LIMIT", 1]]
2.7.3 :002 > user.articles.length
Article Load (1.1ms) SELECT "articles".* FROM "articles" WHERE "articles"."user_id" = $1 [["user_id", 1]]
=> 10
#载入过,不在需要去查询。
2.7.3 :003 > user.articles.length
=> 10
但缺点也很明显Article Load
进资料库里一个一个查。
count
。
当如果没有load
过任何资料,那就请用count
来计算,count
会产生SQL里的count()
函数,
不需要去load
。
2.7.3 :001 > articles = Article.all
Article Load (1.2ms) SELECT "articles".* FROM "articles" /* loading for inspect */ LIMIT $1 [["LIMIT", 11]]
2.7.3 :002 > articles.count
(2.9ms) SELECT COUNT(*) FROM "articles"
=> 10
2.7.3 :006 > articles.length
Article Load (0.8ms) SELECT "articles".* FROM "articles"
=> 10
资料少时,计算可能耗时,但资料多时,就明显效能高很多,一笔一笔去读取...这跟N+1
一样恐怖呀。
但缺点是每次都会计算。
2.7.3 :002 > articles.count
(2.9ms) SELECT COUNT(*) FROM "articles"
=> 10
2.7.3 :003 > articles.count
(0.9ms) SELECT COUNT(*) FROM "articles"
=> 10
2.7.3 :004 > articles.count
(3.3ms) SELECT COUNT(*) FROM "articles"
=> 10
2.7.3 :005 > articles.count
(1.3ms) SELECT COUNT(*) FROM "articles"
=> 10
缺点中的优点是准确,每算一次都会检查一次。
size
。
它不再是谁的别名了,它可以协助你视情况用length
或count
,应该说会帮你判断要去读取还是计数。定义类似如下。
def size
loaded? ? @jobs.length : count
# if loaded?
#@jobs.length
#else
#@jobs.count
#end
end
这是个让你不用去苦恼用length
或count
的好帮手,但是使用这种自动功能,总有个小缺点,当你还是明确希望去count
或length
时,它可能给你执行相反的状况,因为size
不是由你决定用哪个,而是看有没有loaded
。
YA!明天最後一天啦!
<<: [Angular] Day29. Internationalization (i18n)
今天要谈到的观察者模式也是很常见的一个模式,常出现在有两个以上需要互相沟通的物件之间 问题 假设有个...
今天来学学Vue里面的判别式v-if 跟v-show 1.v - if 在这里我们将条件设定为Sho...
おはよう~昨天我们介绍完了四种Collections的其中两种 - List、Tuple,而今天要接...
font-style属性设定HTML元素的文字样式 normal : 正常(预设值) italic ...
RxJava2是一套处理非同步(asynchronous)事件的library,这个library是...