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

喜你入骨 提交于 2019-12-30 13:37:31

问题


I need to count the duplicates, they need to be 100% identical to increase my count, but I can not use a nothing out of Ruby 1.8.5, this code will run inside a plugin in google sketchup

Google Sketchup Ruby API

puts VERSION
1.8.5

puts RUBY_PLATFORM
i686-darwin8.10.1

product = 'Glass'
x = width
y = length
z = density

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}
               ];

product_list_result = product_list.count_duplicate();

product_list_result = [
     { "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}
                      ];

回答1:


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.




回答2:


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



来源:https://stackoverflow.com/questions/12236656/how-to-count-duplicates-hash-itens-in-ruby-1-8-5-sketchup-ruby-api

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