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
Getting a Rogue Iteration from My .Each Loop
Hardcoded "Require 'Debug'" Can't Find the Sourcefile
Rubymine: Expected ; or End of Line Error After Some Colon
Instance_Eval Does Not Work with Do/End Block, Only with {}-Blocks
What Is a More Ruby-Like Way of Doing This Command
How to Create Automatically a Instance of Every Class in a Directory
Ruby Parenthesis Syntax Exception with I++ ++I
Incompatible Character Encoding in Rails - How to Just Fail/Skip Sensibly
Make User-Inputted Url into External Link in Rails
Calling Instance Variables Without @
Ruby: Calculate Time Difference Between 2 Times
Rails 3 - How to Handle Pg Error Incomplete Multibyte Character
Stubbing Controller Actions in Rspec Request Specs
Ruby: Module, Mixins and Blocks Confusing
How to Distribute a Ruby Script via Homebrew
How to Sort So That "Vitamin B12" Is Not in Front of "Vitamin B6"
Restart Rails Server Automatically After Every Change in Controllers