0

我有一个看起来像这样的哈希数组:

[
  {:name=>"CCC_010112.JPG", :type=>"CCC", :date=>"120101"},
  {:name=>"BBB_050112.JPG", :type=>"BBB", :date=>"120501"},
  {:name=>"BBB_040112.JPG", :type=>"BBB", :date=>"120401"},
  {:name=>"BBB_030112.JPG", :type=>"BBB", :date=>"120301"},
  {:name=>"BBB_020112.JPG", :type=>"BBB", :date=>"120201"},
  {:name=>"BBB_010112.JPG", :type=>"BBB", :date=>"120101"},
  {:name=>"AAA_040112.JPG", :type=>"AAA", :date=>"120401"},
  {:name=>"AAA_030112.JPG", :type=>"AAA", :date=>"120301"},
  {:name=>"AAA_020112.JPG", :type=>"AAA", :date=>"120201"},
]

我试图捕捉每种类型的前三个。(例如,我的结果应该产生上面的数组,只删除“BBB”元素的底部两个。我尝试了以下变体:

puts a.each{|e| e[:type]}.take(3) #Shows top 3 of all
4

3 回答 3

3

我会使用Enumerable#chunk,因为在数组中所有不同的类型,如'CCC''BBB'等已经组合在一起了。如果它们是分散的,则group_by首先将不同类型的哈希组合在一起。

a = [
       {:name=>"CCC_010112.JPG", :type=>"CCC", :date=>"120101"},
       {:name=>"BBB_050112.JPG", :type=>"BBB", :date=>"120501"},
       {:name=>"BBB_040112.JPG", :type=>"BBB", :date=>"120401"},
       {:name=>"BBB_030112.JPG", :type=>"BBB", :date=>"120301"},
       {:name=>"BBB_020112.JPG", :type=>"BBB", :date=>"120201"},
       {:name=>"BBB_010112.JPG", :type=>"BBB", :date=>"120101"},
       {:name=>"AAA_040112.JPG", :type=>"AAA", :date=>"120401"},
       {:name=>"AAA_030112.JPG", :type=>"AAA", :date=>"120301"},
       {:name=>"AAA_020112.JPG", :type=>"AAA", :date=>"120201"}
    ]

final_top3_ary = a.chunk { |hash| hash[:type] }.flat_map { |_,ary| ary.take(3) }

final_top3_ary
# => [{:name=>"CCC_010112.JPG", :type=>"CCC", :date=>"120101"},
#     {:name=>"BBB_050112.JPG", :type=>"BBB", :date=>"120501"},
#     {:name=>"BBB_040112.JPG", :type=>"BBB", :date=>"120401"},
#     {:name=>"BBB_030112.JPG", :type=>"BBB", :date=>"120301"},
#     {:name=>"AAA_040112.JPG", :type=>"AAA", :date=>"120401"},
#     {:name=>"AAA_030112.JPG", :type=>"AAA", :date=>"120301"},
#     {:name=>"AAA_020112.JPG", :type=>"AAA", :date=>"120201"}]
于 2014-03-13T22:36:58.370 回答
1

可能有一种更有效的方法,但最重要的是:

a = [
{:name=>"CCC_010112.JPG", :type=>"CCC", :date=>"120101"},
{:name=>"BBB_050112.JPG", :type=>"BBB", :date=>"120501"},
{:name=>"BBB_040112.JPG", :type=>"BBB", :date=>"120401"},
{:name=>"BBB_030112.JPG", :type=>"BBB", :date=>"120301"},
{:name=>"BBB_020112.JPG", :type=>"BBB", :date=>"120201"},
{:name=>"BBB_010112.JPG", :type=>"BBB", :date=>"120101"},
{:name=>"AAA_040112.JPG", :type=>"AAA", :date=>"120401"},
{:name=>"AAA_030112.JPG", :type=>"AAA", :date=>"120301"},
{:name=>"AAA_020112.JPG", :type=>"AAA", :date=>"120201"}
]

a_types = (a.collect { |e| e[:type] }).uniq
a_top3 = []
a_types.each { |t| a_top3 << (a.select { |e| e[:type] == t }).take(3) }
a_top3.flatten!
于 2013-05-29T00:02:47.240 回答
0

由于您在评论中提到您的列表已经反向排序,我们可以使用这个:

top3_of_each = a.inject([]) do |acc, h|
  acc << h if acc.length < 3 || h[:type] != acc[acc.length-3][:type]
  acc
end

如果列表不是反向排序的,那么我们需要做更多的工作来按类型对哈希进行分组并为每种类型找到前 3 个。

于 2013-05-29T01:09:35.630 回答