Layer Names to Array
-
@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
Layerobjects 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
0thru9in 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:
\Athe begin of the string
\Da char that is NOT a digit
\da char that IS a digit
\da 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 tofalseso is not included in the output array fromfind_all.)
The
find_allmethod comes from theEnumerablemixin module, which is mixed into theSketchup::Layersclass, 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
ORthus (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
Hello! It looks like you're interested in this conversation, but you don't have an account yet.
Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.
With your input, this post could be even better 💗
Register LoginAdvertisement