Project1

标题: 请教如何获取数组中某个值的元素个数 [打印本页]

作者: 赛露休斯    时间: 2010-12-8 10:07
标题: 请教如何获取数组中某个值的元素个数
本帖最后由 赛露休斯 于 2010-12-8 10:10 编辑

比如 a = [1,2,3,2,4,2,6,7,2]
如何获取a里面值为2的元素的个数?
我用循环依次对比感觉有些麻烦,而且要处理大数据
作者: 六祈    时间: 2010-12-8 10:20
本帖最后由 六祈 于 2010-12-8 10:28 编辑

Array#index
查了下Ruby文档,发现只有index取单体索引的,你可以自行封装一个方法
  1. class Array
  2. def indexs(value)
  3. _index=[]
  4. self.each_with_index do |x , i|
  5. if x == value
  6. _index << i
  7. end
  8. end
  9. return _index
  10. end
  11. end
复制代码
用的是indexs,是因为indexes是已有方法,虽然目前已废弃使用。。
作者: goahead    时间: 2010-12-8 10:25
提示: 作者被禁止或删除 内容自动屏蔽
作者: 赛露休斯    时间: 2010-12-8 10:28
a = [1,2,3,2,4,2,6,7,2]
p a.index(2) # 1
index 似乎是返回数组中第一个==val的元素的位置
作者: goahead    时间: 2010-12-8 10:47
提示: 作者被禁止或删除 内容自动屏蔽
作者: 赛露休斯    时间: 2010-12-8 10:50
本帖最后由 赛露休斯 于 2010-12-8 10:51 编辑

问题出现了,a里面的元素用字符串,结果。。。
作者: 六祈    时间: 2010-12-8 10:51
本帖最后由 六祈 于 2010-12-8 12:02 编辑

回复 goahead 的帖子

比如
Array#find_all{|item| item == value}.size
或者
Array#inject(0){|number, item| item == value ? number + 1 : number}【多谢紫苏大人提点】

以上纯属交流…
作者: 苏小脉    时间: 2010-12-8 11:20
回复 六祈 的帖子

第一种浪费内存了 XD
第二种是个好东西,源自 Lisp 的 foldl,不过应该是这样:
inject(0) { |number, item| item == value ? number + 1 : number }
这里要保证有整数返回值,否则会返回 nil,下一次的累计值 number 就会变成 nil 了:lol
作者: goahead    时间: 2010-12-8 15:15
提示: 作者被禁止或删除 内容自动屏蔽
作者: 赛露休斯    时间: 2010-12-8 21:01
哦,8L的方法可以用
突然发现用最简单的each循环效率也还真不差(1000多个元素)
作者: 苏小脉    时间: 2010-12-8 21:07
回复 goahead 的帖子

用循环的话在 Ruby 1.8 效率确实更高,但这是一个程序设计泛型的问题。Lisp 的 foldl 这种折合机制是函数式语言的经典函数,只要是函数式语言背景占主要成分的程序员多半都会去用这个 Array#inject,而不是用命令式语言的循环。这里我们又再次看到了 Ruby 多泛型给我们带来的自由。

Ruby 1.9 的 Array#each 是这样:

  1. VALUE
  2. rb_ary_each(VALUE ary)
  3. {
  4.     long i;

  5.     RETURN_ENUMERATOR(ary, 0, 0);
  6.     for (i=0; i<RARRAY_LEN(ary); i++) {
  7.         rb_yield(RARRAY_PTR(ary)[i]);
  8.     }
  9.     return ary;
  10. }
复制代码
它比 1.8 多了一行 RETURN_ENUMERATOR(ary, 0, 0);
这是一个返回枚举器的例程,经费还是颇高的,我做过测试,单单比较 1.9 和 1.8 的 Array#each,1.8 的快许多。所以 1.9 的 each 只怕也比复杂的 Array#inject 快不了多少。
作者: goahead    时间: 2010-12-10 11:29
提示: 作者被禁止或删除 内容自动屏蔽
作者: 苏小脉    时间: 2010-12-10 11:49
回复 goahead 的帖子

inject 没有调用 each。
作者: goahead    时间: 2010-12-10 11:56
提示: 作者被禁止或删除 内容自动屏蔽
作者: 苏小脉    时间: 2010-12-10 12:45
回复 goahead 的帖子

我错了……
  1. rb_block_call(obj, id_each, 0, 0, iter, (VALUE)memo);
复制代码
inject 里有这么一行,id_each == "each"
看来写这个函数的人是想统一接口重用代码,但这样一来就损失效率了,inject 成了 each 的外壳,自然不可能比 each 快。

inject 的设计初衷是为了贯彻 Ruby 自由的哲学,在传统的迭代上再抽象一层,就有了习惯于函数式编程的人熟知的函数。




欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1