How to count duplicates hash itens in Ruby 1.8.5 ( Sketchup Ruby API )

那年仲夏 提交于 2019-12-01 12:28:11

Short answer:

h = Hash.new 0
product_list.each {|p| h[p] += 1}
product_list_result = h.keys.map{|k| k["count"] = h[k]; k}

Longer answer explaining how this works. Starting with your data:

product_list = [
                { "product" => 1, "x" => 200, "y" => 100, "z" => 18},
                { "product" => 1, "x" => 200, "y" => 100, "z" => 18},
                { "product" => 1, "x" => 300, "y" => 100, "z" => 18},
                { "product" => 2, "x" => 300, "y" => 100, "z" => 18},
                { "product" => 2, "x" => 100, "y" => 100, "z" => 18},
                { "product" => 2, "x" => 100, "y" => 100, "z" => 18},
                { "product" => 3, "x" => 100, "y" => 100, "z" => 18}
               ];

# First, create a hash to count the number of unique products. Have the initial
# count be 0.
h = Hash.new 0

# Add each product to the hash count.
product_list.each {|p| h[p] += 1}

Now you have a hash with products as keys, and counts as values:

h = {{"z"=>18, "y"=>100, "x"=>100, "product"=>3}=>1, {"z"=>18, "y"=>100, "x"=>300, "product"=>1}=>1, {"z"=>18, "y"=>100, "x"=>200, "product"=>1}=>2, {"z"=>18, "y"=>100, "x"=>300, "product"=>2}=>1, {"z"=>18, "y"=>100, "x"=>100, "product"=>2}=>2}

Now convert it to the array format you desire:

product_list_result = []
h.keys.each do |k|
    # since each key is a product hash, we can add count to it
    k["count"] = h[k]

    # Now, add that to the array
    product_list_result << k
end

Which results in:

product_list_result = [
                       {"z"=>18, "y"=>100, "x"=>100, "product"=>3, "count"=>1},
                       {"z"=>18, "y"=>100, "x"=>300, "product"=>1, "count"=>1},
                       {"z"=>18, "y"=>100, "x"=>200, "product"=>1, "count"=>2},
                       {"z"=>18, "y"=>100, "x"=>300, "product"=>2, "count"=>1},
                       {"z"=>18, "y"=>100, "x"=>100, "product"=>2, "count"=>2}
                      ]

The array conversion can be done more succinctly:

product_list_result = h.keys.map{|k| k["count"] = h[k]; k}

h.keys returns an array of keys from hash h, which is just the unique products in your list. The function map then replaces each object in that array with the result of the block that follows which simply adds the count value to the product hash.

product_list.dup.group_by { |h| h }.each_value.map do |value| 
  value.first.tap { |hash| hash['count'] = value.count }
end

=> [{"product"=>1, "x"=>200, "y"=>100, "z"=>18, "count"=>2},
 {"product"=>1, "x"=>300, "y"=>100, "z"=>18, "count"=>1},
 {"product"=>2, "x"=>300, "y"=>100, "z"=>18, "count"=>1},
 {"product"=>2, "x"=>100, "y"=>100, "z"=>18, "count"=>2},
 {"product"=>3, "x"=>100, "y"=>100, "z"=>18, "count"=>1}]

dup is for to not modify original product_list

Tested in ruby 1.8.7

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!