0

假设我有

ary = ['aa', 'b', 'cba', 'd', 'df']

并想找到所有匹配的元素的索引/a/。很容易得到相关的值,使用

ary.find_all { |v| v =~ /a/ }
=> ["aa", "cba"]

我想写的是

ary.find_all_indices { |v| v =~ /a/ }

但没有这样的事情。我能想到的只有

(0..ary.size-1).find_all { |i| ary[i] =~ /a/ }
=> [0, 2]

谁能帮我找到更好的东西?

4

4 回答 4

6

没有find_all_indices,但你可以自由组合each_indexfind_all

ary.each_index.find_all{|i| ary[i] =~ /a/}
# => [0, 2]
于 2013-05-16T15:03:31.043 回答
3

总是有兴趣看看什么跑得最快:

require 'benchmark'

N = 10_000
ARY = ('aa' .. 'zz').to_a 
DIVIDER = '-' * 40

def sergio_tulentsev(ary)
  ary.each.with_index.select { |v, idx| v =~ /a/ }.map{|v, i| i}
end

def priti(ary)
  (0..ary.size - 1).each_with_object([]) { |v,ob| ob << v if ary[v].include? 'a'}
end

def darshan_computing(ary)
  ary.each_index.find_all{|i| ary[i] =~ /a/}
end

puts "Ruby version: #{`ruby -v`}"
puts DIVIDER
puts 'Sergio Tulentsev:  ' + sergio_tulentsev(ARY).join(',')
puts 'Priti:             ' + priti(ARY).join(',')
puts 'Darshan Computing: ' + darshan_computing(ARY).join(',')
puts DIVIDER

2.times do
  Benchmark.bm(17) do |b|

    b.report('Sergio Tulentsev')  { N.times { sergio_tulentsev(ARY) }}
    b.report('Priti')             { N.times { priti(ARY) }}
    b.report('Darshan Computing') { N.times { darshan_computing(ARY) }}

  end
end

哪个输出:

Ruby 版本:ruby 1.9.3p392(2013-02-22 修订版 39386)[x86_64-darwin10.8.0]

----------------------------------------
Sergio Tulentsev:  0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,52,78,104,130,156,182,208,234,260,286,312,338,364,390,416,442,468,494,520,546,572,598,624,650
Priti:             0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,52,78,104,130,156,182,208,234,260,286,312,338,364,390,416,442,468,494,520,546,572,598,624,650
Darshan Computing: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,52,78,104,130,156,182,208,234,260,286,312,338,364,390,416,442,468,494,520,546,572,598,624,650
----------------------------------------
                        user     system      total        real
Sergio Tulentsev    4.270000   0.000000   4.270000 (  4.272826)
Priti               2.020000   0.010000   2.030000 (  2.025979)
Darshan Computing   3.690000   0.010000   3.700000 (  3.704790)
                        user     system      total        real
Sergio Tulentsev    4.240000   0.010000   4.250000 (  4.239833)
Priti               2.000000   0.000000   2.000000 (  2.001301)
Darshan Computing   3.700000   0.020000   3.720000 (  3.718807)

Ruby 版本:ruby 1.9.3p429(2013-05-15 修订版 40747)[x86_64-darwin10.8.0]

----------------------------------------
Sergio Tulentsev:  0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,52,78,104,130,156,182,208,234,260,286,312,338,364,390,416,442,468,494,520,546,572,598,624,650
Priti:             0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,52,78,104,130,156,182,208,234,260,286,312,338,364,390,416,442,468,494,520,546,572,598,624,650
Darshan Computing: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,52,78,104,130,156,182,208,234,260,286,312,338,364,390,416,442,468,494,520,546,572,598,624,650
----------------------------------------
                        user     system      total        real
Sergio Tulentsev    4.520000   0.010000   4.530000 (  4.529948)
Priti               2.150000   0.000000   2.150000 (  2.153721)
Darshan Computing   3.370000   0.010000   3.380000 (  3.390537)
                        user     system      total        real
Sergio Tulentsev    4.560000   0.010000   4.570000 (  4.580625)
Priti               2.230000   0.010000   2.240000 (  2.228714)
Darshan Computing   3.560000   0.000000   3.560000 (  3.567562)

Ruby 版本:ruby 2.0.0p0(2013-02-24 修订版 39474)[x86_64-darwin10.8.0]

----------------------------------------
Sergio Tulentsev:  0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,52,78,104,130,156,182,208,234,260,286,312,338,364,390,416,442,468,494,520,546,572,598,624,650
Priti:             0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,52,78,104,130,156,182,208,234,260,286,312,338,364,390,416,442,468,494,520,546,572,598,624,650
Darshan Computing: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,52,78,104,130,156,182,208,234,260,286,312,338,364,390,416,442,468,494,520,546,572,598,624,650
----------------------------------------
                        user     system      total        real
Sergio Tulentsev   13.770000   0.020000  13.790000 ( 13.801769)
Priti               7.760000   0.010000   7.770000 (  7.774238)
Darshan Computing   8.720000   0.020000   8.740000 (  8.743842)
                        user     system      total        real
Sergio Tulentsev   12.930000   0.010000  12.940000 ( 12.948077)
Priti               7.890000   0.010000   7.900000 (  7.898609)
Darshan Computing   8.450000   0.010000   8.460000 (  8.464012)

这些值让我感到惊讶,所以我在不同的时间运行了两次,它们是一致的。

Ruby 版本:ruby 2.0.0p195(2013-05-14 修订版 40734)[x86_64-darwin10.8.0]

----------------------------------------
Sergio Tulentsev:  0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,52,78,104,130,156,182,208,234,260,286,312,338,364,390,416,442,468,494,520,546,572,598,624,650
Priti:             0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,52,78,104,130,156,182,208,234,260,286,312,338,364,390,416,442,468,494,520,546,572,598,624,650
Darshan Computing: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,52,78,104,130,156,182,208,234,260,286,312,338,364,390,416,442,468,494,520,546,572,598,624,650
----------------------------------------
                        user     system      total        real
Sergio Tulentsev    4.890000   0.010000   4.900000 (  4.899299)
Priti               2.110000   0.000000   2.110000 (  2.115395)
Darshan Computing   3.710000   0.010000   3.720000 (  3.727729)
                        user     system      total        real
Sergio Tulentsev    4.960000   0.020000   4.980000 (  4.971293)
Priti               2.170000   0.000000   2.170000 (  2.182052)
Darshan Computing   3.620000   0.010000   3.630000 (  3.623773)

我的机器现在正忙于运行其他东西,所以这些值可能比别人的机器慢一点,尤其是较新的机器,但重要的是相对值。


Ruby v2.0-p0 显示的结果要慢得多。不知道为什么。这是结果,我编写的算法可以减少时间。我认为 Priti 的代码总体上是最好的,尽管我认为它可能会被扭曲并加快速度。

def tinman2(ary)
  idxes = []
  ary.size.times { |idx| (idxes << idx) if (ary[idx] =~ /a/) }
  idxes
end

Ruby version: ruby 2.0.0p0 (2013-02-24 revision 39474) [x86_64-darwin10.8.0]
----------------------------------------
Sergio Tulentsev:  0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,52,78,104,130,156,182,208,234,260,286,312,338,364,390,416,442,468,494,520,546,572,598,624,650
Priti:             0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,52,78,104,130,156,182,208,234,260,286,312,338,364,390,416,442,468,494,520,546,572,598,624,650
Darshan Computing: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,52,78,104,130,156,182,208,234,260,286,312,338,364,390,416,442,468,494,520,546,572,598,624,650
Tinman2:           0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,52,78,104,130,156,182,208,234,260,286,312,338,364,390,416,442,468,494,520,546,572,598,624,650
----------------------------------------
                        user     system      total        real
Sergio Tulentsev   11.600000   0.050000  11.650000 ( 11.646425)
Priti               6.880000   0.020000   6.900000 (  6.903026)
Darshan Computing   7.560000   0.000000   7.560000 (  7.562145)
TheTinMan2          6.690000   0.000000   6.690000 (  6.695731)
                        user     system      total        real
Sergio Tulentsev   11.590000   0.010000  11.600000 ( 11.593051)
Priti               6.880000   0.000000   6.880000 (  6.889174)
Darshan Computing   7.580000   0.000000   7.580000 (  7.573390)
TheTinMan2          6.600000   0.000000   6.600000 (  6.607929)
                        user     system      total        real
Sergio Tulentsev   11.580000   0.010000  11.590000 ( 11.582659)
Priti               6.880000   0.000000   6.880000 (  6.878172)
Darshan Computing   7.590000   0.000000   7.590000 (  7.591342)
TheTinMan2          6.590000   0.000000   6.590000 (  6.598353)

Borodin 要求添加他的算法。我也添加了另一个使用include

def tinman6(ary)
  idxes = []
  ary.size.times { |idx| (idxes << idx) if (ary[idx].include?('a')) }
  idxes
end

def borodin(ary)
  ary.each_index.find_all { |i| ary[i].include? 'a' }
end

Ruby 版本:ruby 1.9.3p392(2013-02-22 修订版 39386)[x86_64-darwin10.8.0]

----------------------------------------
Priti:   0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,52,78,104,130,156,182,208,234,260,286,312,338,364,390,416,442,468,494,520,546,572,598,624,650
Tinman2: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,52,78,104,130,156,182,208,234,260,286,312,338,364,390,416,442,468,494,520,546,572,598,624,650
Tinman6: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,52,78,104,130,156,182,208,234,260,286,312,338,364,390,416,442,468,494,520,546,572,598,624,650
Borodin: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,52,78,104,130,156,182,208,234,260,286,312,338,364,390,416,442,468,494,520,546,572,598,624,650
----------------------------------------
                        user     system      total        real
Priti               1.880000   0.000000   1.880000 (  1.874891)
TheTinMan2          3.330000   0.000000   3.330000 (  3.337149)
TheTinMan6          1.660000   0.000000   1.660000 (  1.658698)
Borodin             1.740000   0.000000   1.740000 (  1.738520)
                        user     system      total        real
Priti               1.870000   0.000000   1.870000 (  1.872923)
TheTinMan2          3.320000   0.000000   3.320000 (  3.314796)
TheTinMan6          1.650000   0.000000   1.650000 (  1.650655)
Borodin             1.730000   0.000000   1.730000 (  1.732083)
                        user     system      total        real
Priti               1.870000   0.000000   1.870000 (  1.871353)
TheTinMan2          3.330000   0.000000   3.330000 (  3.332134)
TheTinMan6          1.650000   0.000000   1.650000 (  1.651290)
Borodin             1.730000   0.000000   1.730000 (  1.731993)

Ruby 版本:ruby 1.9.3p429(2013-05-15 修订版 40747)[x86_64-darwin10.8.0]

----------------------------------------
Priti:   0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,52,78,104,130,156,182,208,234,260,286,312,338,364,390,416,442,468,494,520,546,572,598,624,650
Tinman2: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,52,78,104,130,156,182,208,234,260,286,312,338,364,390,416,442,468,494,520,546,572,598,624,650
Tinman6: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,52,78,104,130,156,182,208,234,260,286,312,338,364,390,416,442,468,494,520,546,572,598,624,650
Borodin: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,52,78,104,130,156,182,208,234,260,286,312,338,364,390,416,442,468,494,520,546,572,598,624,650
----------------------------------------
                        user     system      total        real
Priti               1.840000   0.000000   1.840000 (  1.833698)
TheTinMan2          3.090000   0.000000   3.090000 (  3.095056)
TheTinMan6          1.680000   0.000000   1.680000 (  1.676831)
Borodin             1.760000   0.000000   1.760000 (  1.766091)
                        user     system      total        real
Priti               1.840000   0.000000   1.840000 (  1.834253)
TheTinMan2          3.100000   0.000000   3.100000 (  3.102027)
TheTinMan6          1.720000   0.000000   1.720000 (  1.726131)
Borodin             1.780000   0.000000   1.780000 (  1.772062)
                        user     system      total        real
Priti               1.830000   0.000000   1.830000 (  1.833505)
TheTinMan2          3.110000   0.000000   3.110000 (  3.107236)
TheTinMan6          1.670000   0.000000   1.670000 (  1.677120)
Borodin             1.770000   0.000000   1.770000 (  1.763458)

Ruby 版本:ruby 2.0.0p0(2013-02-24 修订版 39474)[x86_64-darwin10.8.0]

----------------------------------------
Priti:   0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,52,78,104,130,156,182,208,234,260,286,312,338,364,390,416,442,468,494,520,546,572,598,624,650
Tinman2: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,52,78,104,130,156,182,208,234,260,286,312,338,364,390,416,442,468,494,520,546,572,598,624,650
Tinman6: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,52,78,104,130,156,182,208,234,260,286,312,338,364,390,416,442,468,494,520,546,572,598,624,650
Borodin: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,52,78,104,130,156,182,208,234,260,286,312,338,364,390,416,442,468,494,520,546,572,598,624,650
----------------------------------------
                        user     system      total        real
Priti               6.860000   0.030000   6.890000 (  6.891947)
TheTinMan2          6.680000   0.030000   6.710000 (  6.705629)
TheTinMan6          6.170000   0.000000   6.170000 (  6.175578)
Borodin             7.060000   0.000000   7.060000 (  7.058933)
                        user     system      total        real
Priti               6.820000   0.000000   6.820000 (  6.828020)
TheTinMan2          6.600000   0.000000   6.600000 (  6.600167)
TheTinMan6          6.050000   0.010000   6.060000 (  6.046283)
Borodin             6.870000   0.000000   6.870000 (  6.868911)
                        user     system      total        real
Priti               6.840000   0.000000   6.840000 (  6.847487)
TheTinMan2          6.600000   0.000000   6.600000 (  6.599859)
TheTinMan6          6.060000   0.000000   6.060000 (  6.058301)
Borodin             6.880000   0.000000   6.880000 (  6.886744)

Ruby 版本:ruby 2.0.0p195(2013-05-14 修订版 40734)[x86_64-darwin10.8.0]

----------------------------------------
Priti:   0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,52,78,104,130,156,182,208,234,260,286,312,338,364,390,416,442,468,494,520,546,572,598,624,650
Tinman2: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,52,78,104,130,156,182,208,234,260,286,312,338,364,390,416,442,468,494,520,546,572,598,624,650
Tinman6: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,52,78,104,130,156,182,208,234,260,286,312,338,364,390,416,442,468,494,520,546,572,598,624,650
Borodin: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,52,78,104,130,156,182,208,234,260,286,312,338,364,390,416,442,468,494,520,546,572,598,624,650
----------------------------------------
                        user     system      total        real
Priti               1.900000   0.010000   1.910000 (  1.908870)
TheTinMan2          3.330000   0.020000   3.350000 (  3.353368)
TheTinMan6          1.800000   0.000000   1.800000 (  1.807138)
Borodin             1.780000   0.010000   1.790000 (  1.786934)
                        user     system      total        real
Priti               1.890000   0.010000   1.900000 (  1.896419)
TheTinMan2          3.320000   0.010000   3.330000 (  3.331743)
TheTinMan6          1.810000   0.010000   1.820000 (  1.821966)
Borodin             1.790000   0.000000   1.790000 (  1.784046)
                        user     system      total        real
Priti               1.880000   0.000000   1.880000 (  1.884283)
TheTinMan2          3.330000   0.000000   3.330000 (  3.332970)
TheTinMan6          1.810000   0.000000   1.810000 (  1.812595)
Borodin             1.780000   0.010000   1.790000 (  1.782502)
于 2013-05-16T15:54:18.120 回答
1
ary = ['aa', 'b', 'cba', 'd', 'df']
(0..ary.size - 1).each_with_object([]) { |v,ob| ob << v if ary[v].include? 'a'}
# => [0, 2]
于 2013-05-16T15:13:18.933 回答
0

这也是一个简单的解决方案。

不打扰地图,因为这是通过块中索引的集合完成的。另外,使用地图,无论如何我都必须删除nil条目,也许使用uniq然后忽略一次出现nil

indices = []
%w[here there are not many words with an a in them].each_with_index {|word, i| indices << i if word =~ /a/}

希望能帮助到你。

于 2013-05-16T21:56:16.930 回答