Layer Names to Array
-
I used this line of code to make an array of layer names. However it makes an array of layers not layer names.
layers = model.layers lname = layers.each {|e| e.name}
It seems that I need to move the lname = inside the brackets but I had no sucess with what I tried. How should I make the array of names?
Question 2: When I have the layer names how would I select a name that has only characters 0 thru 9 in lname(1,2)?
Keith
-
You are using
each
instead ofmap
.Correct is:
<span class="syntaxdefault"><br />layers </span><span class="syntaxkeyword">= </span><span class="syntaxdefault">model</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">layers<br />lname </span><span class="syntaxkeyword">= </span><span class="syntaxdefault">layers</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">map </span><span class="syntaxkeyword">{ |</span><span class="syntaxdefault">e</span><span class="syntaxkeyword">| </span><span class="syntaxdefault">e</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">name </span><span class="syntaxkeyword">}<br /> </span><span class="syntaxdefault"></span>
-
@ktkoh said:
Question 2: When I have the layer names how would I select a name that has only characters 0 thru 9 in lname(1,2)?
You refer to the ASCII character code?
Or you want the first 9 characters in the string?(Beware that strings from SketchUp, such as layer names etc., is UTF-8 encoded - while Ruby 1.8 treats characters in a string as single bytes. Meaning if you extract the first 9 bytes of a string you might chop a UTF-8 character in half. Further reading: http://forums.sketchucation.com/viewtopic.php?f=180&t=20657 )
-
It would be more logical to give your array a 'plural name' so it's more obviously a 'collection'
lnames = model.layers.map{|e| e.name }
Then
lnames9 = lnames.map{|e| e.length <= 9 }
B_U_T... as TT says - non-ASCII characters can give a false 'length' as they use 'two' bits...
t="cat" cat t.length 3 t="cat½" cat½ t.length 5
i.e. NOT 4 ... the '½' appears as one character but it takes two bits... -
This snippet finds all layers with less than 9 unicode characters:
<span class="syntaxdefault"><br />lnames </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> model</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">layers</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">map </span><span class="syntaxkeyword">{</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">|</span><span class="syntaxdefault">layer</span><span class="syntaxkeyword">|</span><span class="syntaxdefault"> layer</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">name </span><span class="syntaxkeyword">}<br /></span><span class="syntaxdefault">lnames9 </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> lnames</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">select </span><span class="syntaxkeyword">{</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">|</span><span class="syntaxdefault">layername</span><span class="syntaxkeyword">|</span><span class="syntaxdefault"> layername</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">unpack</span><span class="syntaxkeyword">(</span><span class="syntaxstring">'U*'</span><span class="syntaxkeyword">).</span><span class="syntaxdefault">length </span><span class="syntaxkeyword"><=</span><span class="syntaxdefault"> 9 </span><span class="syntaxkeyword">}<br /> </span><span class="syntaxdefault"></span>
Or, if you want to collect the
Layer
objects directly:<span class="syntaxdefault"><br />lnames9 </span><span class="syntaxkeyword">= </span><span class="syntaxdefault">model</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">layers</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">select </span><span class="syntaxkeyword">{ |</span><span class="syntaxdefault">layer</span><span class="syntaxkeyword">| </span><span class="syntaxdefault">layer</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">name</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">unpack</span><span class="syntaxkeyword">(</span><span class="syntaxstring">'U*'</span><span class="syntaxkeyword">).</span><span class="syntaxdefault">length </span><span class="syntaxkeyword"><= </span><span class="syntaxdefault">9 </span><span class="syntaxkeyword">}<br /> </span><span class="syntaxdefault"></span>
-
No guys he wants names that have numerical characters in the 2nd and 3rd positions.
@unknownuser said:
... only characters
0
thru9
in lname(1,2
)?
A regular expression is easiest:
num_layers = model.layers.find_all { |layer| layer.name =~ /\A\D\d\d/ } num_layer_names = num_layers.map { |layer| layer.name }
The pattern escape sequences mean:
\A
the begin of the string
\D
a char that is NOT a digit
\d
a char that IS a digit
\d
a char that IS a digit
.. and we don't care about the rest of the name.If we get a match, the integer char position of the match (and will be 0 because we used
\A
,) is returned by the=~
method, otherwise for no match it returnsnil
(which evals tofalse
so is not included in the output array fromfind_all
.)
The
find_all
method comes from theEnumerable
mixin module, which is mixed into theSketchup::Layers
class, viz:
Sketchup::Layers.ancestors %(#008000)[>> [Sketchup::Layers, Enumerable, Sketchup::Entity, Object, Kernel]]
-
Thanks for your help. Dan was correct the pattern I am looking for starts A00- thru A99- and his code worked very well.
Keith
-
For more on Regular Expressions, see the old "Pick-Axe" book:
Programming Ruby: The Ruby Language (Regular Expressions) -
Is regex unicode aware by default in Ruby 1.8, or do you have to enable a flag? There is still the risk of getting part of a multi-bye character if it isn't.
-
@thomthom said:
Is regex unicode aware by default in Ruby 1.8, or do you have to enable a flag? There is still the risk of getting part of a multi-bye character if it isn't.
OK.. IF the first character is unicode and multi-byte, he could use a
OR
thus (and I add into the pattern the dash he has after the two digits):num_layers = model.layers.find_all { |layer| layer.name =~ /\A\D\d\d-/ || # 1st char multibyte unicode # m opt allows . bytes to be any char layer.name =~ /\A..\d\d-/m }
-
I thought you might find this interesting:
Last night I copied and pasted Dan's code into the web console and the code worked as expected. I added the dash at the end and also added a line to sort the file names still working. Wife says baseball is starting so I save the snippet and go in to watch the Reds. Now this morning I reload the saved file and nothing works. So I repeat the process from last evening and after pasting Dan's code in it again works. I have experimented today and found in the web console I cannot save and reload the code and get it to work. Any Thoughts on this??Keith
-
There are different verions of the webconsole out there - which one do you use?
-
I use webconsole.rb Copyright (C) 2006 Jim Foltz
and have not looked for updates.Keith
Advertisement