Advertisement

MaxScript error when trying to operate on strings

Started by June 01, 2011 05:07 PM
1 comment, last by Kryzon 13 years, 6 months ago
Hello,

I am writing an exporter in MaxScript (using 2011) and am having trouble with a function thats meant to clean spaces from strings:

function CleanSpaces str_in
=(
str_out = (copy str_in as string)

for i = 1 to (str_out.count as Integer) do
(
if(str_out == " ")then
(
str_out = "_"
)
)

str_out
)



When I copy this into the listener and enter any string I recieve the following:

cleanspaces "example string"
-- Error occurred in i loop
-- Frame:
-- i: 1
-- called in CleanSpaces()
-- Frame:
-- str_out: "example string"
-- str_in: "example string"
-- Type error: Call needs function or class, got: undefined


I cannot see any problem with this simple function, is there anyone familiar with MaxScript who could tell me whats wrong?

Thanks!
Just tested with Max 9, got no error. It converted "bla bli ble" to "bla_bli_ble".

But in any case I would do this differently; there are some things in there that you could optimize.


 -- A side effect of this implementation is that it trims spaces at the start or end.

function CleanSpaces str_in =(

    local temp = filterString str_in " "
    local amount = temp.count - 1 -- Precalculate the amount of tokens so as not to keep evaluating ".count" every iteration.
    local str_out = ""

    for i in 1 to amount do (
        str_out += (temp + "_")
    )

    (str_out + temp[temp.count])
)
 
Advertisement
Hi again, now with more time I could think better. You see, in that function I posted it would remove consecutive spaces and that might not be what you're after: something with five spaces between words would have them replaced with just one. It wouldn't be consistent with the input.

So the original function gives a better result. With that in mind, we can try other ways to optimize it (just for the heck of it; also because you're writing an exporter and need all the nanoseconds you can get).

Here is a little speed test with two different versions: the original and one that uses the 'Where' expression instead of an 'If'.

function CleanSpaces1 str_in = ( -- ORIGINAL
    str_out = (copy str_in as string)

    for i = 1 to (str_out.count as Integer) do
    (
        if(str_out == " ") do -- Changed to 'do'.
        (
            str_out = "_"
        )
    )

    str_out
)

function CleanSpaces2 str_in = ( -- USING 'WHERE'
    local str_out = copy (str_in as string)
    size = str_in.count

    for i = 1 to size where (str_out == " ") do (
        str_out = "_"
    )

    str_out
)

start = timeStamp()
for i = 1 to 1500 do (
    CleanSpaces1 "foo bar      is nice."
)
format "Time taken for original: %" (timeStamp() - start)

start = timeStamp()
for i = 1 to 1500 do (
    CleanSpaces2 "foo bar      is nice."
)
format "Time taken for 'Where' version: %" (timeStamp() - start)

Everytime I evaluated (CTRL+E) the above, the "Where" version ran a few milliseconds faster.
Also, "If ... Then" expressions are slower than "If ... Do" ones (because they allow an "Else" to be added). So any time you need an "If" that doesn't require an "Else", use a "Do" for these single block conditions. 

While there are a few MaxScript threads here, I can't recommend enough the CGSociety forums where they have  a whole subforum for the MaxScript language. Plenty of technical artists over there, it's not only a great place to ask questions but to read the discussions as well.
Make sure to read the  How To Make It Faster? article that comes with the MaxScript documentation, it explains several good practices and some very effective optimizations. 

This topic is closed to new replies.

Advertisement