通过Ruby中的第一个字母搜索数组?

时间:2016-11-10 15:56:53

标签: arrays ruby

我有一个数组:

dictionary = [ 
  'abnormal',
  'arm-wrestling',
  'absolute',
  'airplane',
  'airport',
  'amazing',
  'apple',
  'ball'
]

我如何通过他们的第一个字母搜索前五场比赛,如果没有五场比赛,那么我会更少?

input = "a"
match = dictionary.select { |a| a.match(input) }
puts match

match返回

["abnormal", "arm-wrestling", "absolute", "airplane", "airport", "amazing", "apple", "ball"]

但我需要它返回

["abnormal", "arm-wrestling", "absolute", "airplane", "airport"]

并且不会因为它包含“a”而返回["ball"]之类的字词。

3 个答案:

答案 0 :(得分:7)

如果我理解正确,您需要前五个以'a'开头的单词。

您可以使用String#start_with?

dictionary.select { |word| word.start_with?('a') }.first(5)

为了获得更好的表现,您可以lazy选择这五个字。如果您正在进行搜索的集合越来越大,那将特别有意义:

dictionary.lazy.select { |word| word.start_with?('a') }.first(5)

对于不区分大小写的选择:

dictionary.lazy.select { |word| word.start_with?('a', 'A') }.first(5)

答案 1 :(得分:3)

▶ dictionary.group_by { |w| w[0] }
#⇒ {
#    "a" => [
#        [0] "abnormal",
#        [1] "arm-wrestling",
#        [2] "absolute",
#        [3] "airplane",
#        [4] "airport",
#        [5] "amazing",
#        [6] "apple"
#    ],
#    "b" => [
#        [0] "ball"
#    ]
# }

dictionary.group_by { |w| w[0] }['a'].take(5)将返回请求的数组。

或使用grep

dictionary.grep(/\Aa/).take(5)

或懒惰:

dictionary.lazy.grep(/\Aa/).first(5)

答案 2 :(得分:1)

看起来有很多答案被抛弃而不考虑处理速度。这并没有尝试衡量返回前五个单词,只是确定单词是否以'a'开头:

words = %w[
  aback
  agonizing
  bell
  bubble
  dear
  lackadaisical
  mouth
  nonstop
  rinse
  steel
  stroke
]

var = 'a'

require 'fruity'

这比较所有:

var = 'a'
compare do
  starts_with { words.select { |w| w.start_with?('a') } }
  downcase { words.select { |w| w.downcase.start_with?('a') } }
  regexp { words.select { |w| w[0] =~ /a/i } }
  mudasobwa1 { words.select { |a| %w|a A|.include? a[0] } }
  mudasobwa2 { words.group_by { |w| w[0] }['a'] }
  mudasobwa3 { words.grep(/\Aa/).to_a }
  mudasobwa4 { words.lazy.grep(/\Aa/).to_a }
  stefan { words.select { |word| word.start_with?('a', 'A') } }
  andrey_deinko { words.select { |a| a[0] =~ /#{var}/ }}
  andrey_deinko2 { words.lazy.select { |word| word.start_with?('a') }.to_a }
end

# >> Running each test 2048 times. Test will take about 4 seconds.
# >> starts_with is similar to stefan
# >> stefan is similar to downcase
# >> downcase is faster than mudasobwa1 by 2x ± 0.1
# >> mudasobwa1 is similar to mudasobwa3
# >> mudasobwa3 is similar to regexp
# >> regexp is similar to mudasobwa2
# >> mudasobwa2 is similar to andrey_deinko2
# >> andrey_deinko2 is similar to mudasobwa4
# >> mudasobwa4 is faster than andrey_deinko by 4x ± 1.0

为了尝试帮助lazy方法,我将words数组的大小扩展了1000:

words = (%w[
  aback
  agonizing
  bell
  bubble
  dear
  lackadaisical
  mouth
  nonstop
  rinse
  steel
  stroke
] * 1000).shuffle

Rerunning显示:

# >> Running each test 2 times. Test will take about 4 seconds.
# >> starts_with is similar to stefan
# >> stefan is similar to andrey_deinko2
# >> andrey_deinko2 is similar to downcase
# >> downcase is similar to mudasobwa2
# >> mudasobwa2 is similar to mudasobwa1
# >> mudasobwa1 is similar to mudasobwa3
# >> mudasobwa3 is similar to mudasobwa4
# >> mudasobwa4 is similar to regexp
# >> regexp is faster than andrey_deinko by 9x ± 1.0

使用正则表达式需要付出很高的代价才能学会使用锚点。我不会在这里进入它,但有关于SO的问题和答案显示差异所以搜索它们。

保持简单。利用为此目的设计的内置方法。