Outliner selection not in Order
-
Selecting an array of components from outliner and ruby returns the list NOT in the order shown in Outliner.
This displays the comp namesmod = Sketchup.active_model # Open model ent = mod.entities # All entities in model sel = mod.selection # Current selection sel.each { |e| UI.messagebox("Sel Array " + e.definition.name.to_s)}
I tried sorting but either of these show error no method for sort.
sel.sort!
sel.sort! { |e| e.definition.name }
I need the list of entities but sorted by name
Keith
-
Perhaps
sel.to_a.sort
might work ?
BUT, to sort the definition names [properly], I suggest you 'start at the other end' !
names = sel.grep(Sketchup::ComponentInstance).collect{|i| i.definition.name }.sort
that's a sorted list of selected instances' definition-names... -
mod = Sketchup.active_model # Open model ent = mod.entities # All entities in model sel = mod.selection # Current selection names = [] sel.each { |e| names.push(e.definition.name)} p names.sort
-
That is still not the result I am looking for. I need the sel entity list (all entities are comp instances) but the entities should be in order by their def name. I can't see a way to get back to the entities from the name list. Perhaps a better way would be to sort the pages after completion. I don't know if that is possible
thanks
Keith -
How about this: you need to tell sort that you want to compare the names to determine order.
sorted = sel.grep(Sketchup;;ComponentInstance).sort {|a,b| a.name <=> b.name}
If you want to use the definition names, just insert .definition between a,b and .name
-
Once you have a list of ordered definitions 'names' you can then access them using something like this:
defns=[]; names.each{|name| defns << model.definitions[name] }
then you have 'defns
' as an ordered list of definitions, arranged by their previously sorted names...
This is not, thus far, rocket-science... -
TIG It may not be rocket science but so far none of the ideas has helped me get a list of instances sorted by the component name. Now if I temp add a instance name = definition name would that make the list easier sortable?? I came to programing late in life so it is not like a second language to me and I have appreciated the forum help. I hope I have not asked too often. I do look for examples and try several ideas before I ask here.
Thanks
Keith -
Let's start back at the beginning...
I now think I see what you want to do...
It wasn't obvious thus far...
Please don't be put off asking - just ask as clearly as you can.You have a selected 'sub-set' of the current context's entities.
You want to list any instances in that selection, arranged in the order of their definition-names.model=Sketchup.active_model instances=model.selection.grep(Sketchup;;ComponentInstance) ### an array of instances, unsorted. ### Make a list of definition names names=[] instances.each{|i| names << i.definition.name unless names.include?(i.definition.name) } names.sort! ### an array of definition-names sorted alphabetically. sorted_instances=[] names.each{|name| instances.dup.each{|i| if i.definition.name==name sorted_instances << i instances.delete(i) end } } ### we now have an array of instances sorted by their definition-names alphabetically.
To get all instances in the active context [no selection considered], then substitute:
instances=model.active_entities.grep(Sketchup::ComponentInstance)
-
.
I need to point out again that Steve gave the correct answer@slbaumgartner said:
How about this: you need to tell
sort
that you want to compare the names to determine order.sorted = sel.grep(Sketchup;;ComponentInstance).sort {|a,b| a.name <=> b.name}
If you want to use the definition names, just insert
.definition
between a,b and.name
So following the last sentence (in Steve's post,) you insert the
.definition
into the block twice, thus:sorted = sel.grep(Sketchup;;ComponentInstance).sort {|a,b| a.definition.name <=> b.definition.name }
The block uses
<=>
, which is the Ruby comparison method.This means that the expressions on each side of the
<=>
must be comparable, which means that at the least, their class must define a<=>
method (and might also mixin in theComparable
module.) -
Thanks Dan when I added definition where you suggested that code worked very well. I had been adding it in the wrong place after the instance. And I appreciated the English description of what the code was saying.
THANKS TO ALL THE FORUM CONTRIBUTORS THAT HAVE HELPED ME!! I seem to have the ability to imagine programs that would help speed up manual operations but using the API samples to write code is a crap shoot at best. Would have not bothered without the great help available here.mod = Sketchup.active_model # Open model
ent = mod.entities # All entities in model
sel = mod.selection # Current selectionsorted = []
sorted = sel.grep(Sketchup::ComponentInstance).sort {|a,b| a.definition.name <=> b.definition.name}
sorted.each { |e| UI.messagebox(e.definition.name)}[/code] -
You do not need
sorted = []
, asgrep
makes a new array, thensort
makes another new array.Save yourself some grief. Use
puts
orpp
output to the console, rather thanUI.messagebox
, for testing. (UI.messagebox
can fail silently if the C WinAPI functions do not like the string passed to them.)
Advertisement