我只是在学习Ruby,并且一直在处理小代码项目以加速这个过程。
我在这里要做的只是将文本文件中的字母单词读入数组,然后删除数组中长度小于5个字符的单词。然后stdout位于底部,我打算使用该数组。我的代码目前有效,但速度非常慢,因为它必须读取整个文件,然后单独检查每个元素并删除相应的元素。这似乎做得太多了。
goal = File.read('big.txt').split(/\s/).map do |word|
word.scan(/[[:alpha:]]+/).uniq
end
goal.each { |word|
if word.length < 5
goal.delete(word)
end
}
puts goal.sample
有没有办法将条件应用于我的File.read块,以防止它从短字开始映射?我愿意接受任何有助于我加快速度的事情。
答案 0 :(得分:3)
您可能希望更改正则表达式,而不是仅捕获长度超过5个字符的单词:
goal = File.read('C:\Users\bkuhar\Documents\php\big.txt').split(/\s/).flat_map do |word|
word.scan(/[[:alpha:]]{6,}/).uniq
end
进一步优化可能是维护Set
而不是Array
,以避免重新扫描唯一性:
goal = Set.new
File.read('C:\Users\bkuhar\Documents\php\big.txt').scan(/\b[[:alpha:]]{6,}\b/).each do |w|
goal << w
end
答案 1 :(得分:2)
在这种情况下,请使用delete_if方法
goal => your array
goal.delete_if{|w|w.length < 5}
这将返回一个新数组,其中长度小于5的单词已被删除。
希望这有帮助。
答案 2 :(得分:1)
我真的不明白你在第一个循环中做的很多东西是为了什么。
您将每个文本块分隔为空格,并将其映射到通过将字母组字符串组合在一起生成的数组中的唯一值,并将其插入到数组中。
这对你想要的东西太复杂了。试试这个:
goal = File.readlines('big.txt').select do |word|
word =~ /^[a-zA-Z]+$/ &&
word.length >= 5
end
这也可以轻松添加新条件。如果这个词不能包含&#39; q&#39;或者&#39; Q&#39;,例如:
goal = File.readlines('big.txt').select do |word|
word =~ /^[a-zA-Z]+$/ &&
word.length >= 5 &&
! word.upcase.include? 'Q'
end
这假定词典中的每个单词都在自己的行上。你可以回去把它分成白色空间,但它让我想知道你正在读的文件是否是人类可读的文字; a.k.a,它有&#39;字&#39;以句号或逗号结尾,如句子。在这种情况下,拆分空格将无效。
另一个注意事项 - map是要使用的错误数组函数。它修改一个数组中的值,并从这些值中创建另一个值。您想从数组中选择某些值,但不要修改它们。 Array#select方法就是您想要的。
另外,如果您希望使用非标准字母字符,请随意将Regex修改为使用:alpha:标记。
编辑:第二版
goal = /([a-z][a-z']{4,})/gi.match(File.readlines('big.txt').join(" "))[1..-1]
说明:加载文件,并将空间中的所有行连接在一起。捕获一组字母的所有出现,至少5个长并且可能包含但不以'
开头。将所有出现的事件放入数组中。 [1 ..- 1]丢弃&#34;完全匹配&#34;由MatchData对象返回,这将是所有附加在一起的单词。
这很有效,而且它对你的整个任务只有一行,但它匹配
sugar'
in
I'd like some 'sugar', if you know what I mean
如上所述,如果您的字词不能包含q
或Q
,则可以将正则表达式更改为
/[a-pr-z][a-pr-z']{4,})[ .'",]/i
一个想法 - 在goal
上执行另一个选择,删除所有以'
结尾的条目。这克服了我的正则表达式的局限性