How to Count Duplicates Hash Itens in Ruby 1.8.5 ( Sketchup Ruby API )

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

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.

How do I iterate over an array of hashes and count the duplicate results in Ruby

This question has been answered before, but there is always room for improvement:

a = [{:name=>"John Doe1", :number=>"5551234567"},
{:name=>"John Doe1", :number=>"5551234567"},
{:name=>"John Doe2", :number=>"5557654321"},
{:name=>"John Doe1", :number=>"5551234567"}]

a.group_by{|h|h}.map{|k,v|k[:count]=v.size;k}
# => [{:name=>"John Doe1", :number=>"5551234567", :count=>3},
# {:name=>"John Doe2", :number=>"5557654321", :count=>1}]

how to know face contain another face with ruby api in sketchup

This can be determined by comparing the loops that make up the face.

Face.outerloop will return the loop that bounds a face (excluding any internal edges). Face.loop returns all of a face's loops including inner and outer.

So, by getting a list of all connected faces (using the example code with all_connected that you posted), you can iterate over those faces to determine if any of faceA's outerloop is shared by the iterated face. If so, it is not an inset face, rather it is adjacent.

There is an alternative method posted here that might be a good way to go too: https://forums.sketchup.com/t/how-to-know-that-a-face-contains-another-face-using-ruby-api/21840/3

Note, in the linked post, they comment that you can't directly compare loops, but you can compare edges (which compose a loop).

Merge duplicates in array of hashes

I can think of as

arr = [
{name: 'one', tags: 'xxx'},
{name: 'two', tags: 'yyy'},
{name: 'one', tags: 'zzz'},
]

merged_array_hash = arr.group_by { |h1| h1[:name] }.map do |k,v|
{ :name => k, :tags => v.map { |h2| h2[:tags] }.join(" ,") }
end

merged_array_hash
# => [{:name=>"one", :tags=>"xxx ,zzz"}, {:name=>"two", :tags=>"yyy"}]

SketchUp API: How to add a check box to a menu item

SketchUp can have check marks in menu items. Both menu items and commands can have a validation proc. The documentation for set_validation_proc gives this example:

plugins_menu = UI.menu("Plugins")
item = plugins_menu.add_item("Test") { UI.messagebox "My Test Item"}
status = plugins_menu.set_validation_proc(item) {
if Sketchup.is_pro?
MF_ENABLED
else
MF_GRAYED
end
}

Although for checkmarks you would use the constants MF_CHECKED and MF_UNCHECKED

http://www.sketchup.com/intl/en/developer/docs/ourdoc/menu#set_validation_proc

http://www.sketchup.com/intl/en/developer/docs/ourdoc/command#set_validation_proc

How to count duplicate elements in a Ruby array

The following code prints what you asked for. I'll let you decide on how to actually use to generate the hash you are looking for:

# sample array
a=["aa","bb","cc","bb","bb","cc"]

# make the hash default to 0 so that += will work correctly
b = Hash.new(0)

# iterate over the array, counting duplicate entries
a.each do |v|
b[v] += 1
end

b.each do |k, v|
puts "#{k} appears #{v} times"
end

Note: I just noticed you said the array is already sorted. The above code does not require sorting. Using that property may produce faster code.

How to count duplicates in Ruby Arrays

This will yield the duplicate elements as a hash with the number of occurences for each duplicate item. Let the code speak:

#!/usr/bin/env ruby

class Array
# monkey-patched version
def dup_hash
inject(Hash.new(0)) { |h,e| h[e] += 1; h }.select {
|k,v| v > 1 }.inject({}) { |r, e| r[e.first] = e.last; r }
end
end

# unmonkeey'd
def dup_hash(ary)
ary.inject(Hash.new(0)) { |h,e| h[e] += 1; h }.select {
|_k,v| v > 1 }.inject({}) { |r, e| r[e.first] = e.last; r }
end

p dup_hash([1, 2, "a", "a", 4, "a", 2, 1])
# {"a"=>3, 1=>2, 2=>2}

p [1, 2, "Thanks", "You're welcome", "Thanks",
"You're welcome", "Thanks", "You're welcome"].dup_hash
# {"You're welcome"=>3, "Thanks"=>3}


Related Topics



Leave a reply



Submit