0

Currently, I'm doing this:

(in initialize)
 @all = Stuff.all.each.map {|t| t.reference_date }
 @uniques = @all.uniq



results = []
@uniques.each do |k|
  i = 0
  @all.each do |x|
    i += 1 if x =~ %r{#{x}}
  end
  results << [k, i]
end

And that's fine. It's going to work. But I like to avoid regular expressions when I can. I think they are a bit feo. That's spanish for ugly.

EDIT-- actually, that's not working because ruby "puts" the date as a numbered format like 2012-03-31 when the date object is placed inside of a string (as a variable, here), but its really a date object, so this worked:

if x.month == k.month && x.day == k.day
  i += 1
end
4

5 回答 5

2

您只需 1 行就可以完成(如果我的问题当然是正确的):

array = %w(a b c d a b d f t z z w w)
# => ["a", "b", "c", "d", "a", "b", "d", "f", "t", "z", "z", "w", "w"]
array.uniq.map{|i|[i, array.count(i)]}
# => [["a", 2], ["b", 2], ["c", 1], ["d", 2], ["f", 1], ["t", 1], ["z", 2], ["w", 2]]
于 2012-11-02T21:02:01.530 回答
1

您可以采取一些措施来避免出现正则表达式,即使用Regexp.union. 您可能想要这样做的原因是速度。构造良好的正则表达式比迭代列表更快,尤其是大列表。而且,通过允许您的代码构建正则表达式,您不必维护一些丑陋(feo)的东西。

例如,这是我在不同代码块中所做的事情:

words = %w[peer_address peer_port ssl ssl_protocol ssl_key_exchange ssl_cipher]
regex = /\b(?:#{ Regexp.union(words).source })\b/i
=> /\b(?:peer_address|peer_port|ssl|ssl_protocol|ssl_key_exchange|ssl_cipher)\b/i

这使得维护正则表达式变得微不足道。并且,尝试使用它来查找文本中的子字符串以防止迭代,它会给你留下深刻印象。

于 2012-11-02T21:33:28.340 回答
1
results = Hash.new(0)
@all.each{|t| results[t] += 1}
# stop here if a hash is good enough.
# if you want a nested array:
results = results.to_a

这是获取可枚举元素频率的标准方法。

于 2012-11-02T21:06:16.370 回答
0

如果通配符对您有用,请尝试File.fnmatch

于 2012-11-02T20:47:36.533 回答
0

从您的代码中,我感觉到您想要获取每个reference_date. 这可以通过直接使用 ActiveRecord 和 SQL 来实现,而不是提取整个故事,然后在 Ruby 中执行耗时的操作。

如果您使用的是 Rails 2.x,则可以使用以下内容:

Stuff.find(:all, :select => "reference_date, COUNT(*)", :group => "reference_date")

或者如果您使用的是 Rails 3,那么您可以将其简化为

Stuff.count(:group => "reference_date")
于 2012-11-03T07:35:00.593 回答