textSubStr Confusion
Rainbros
Member Posts: 124
I was just playing around with the textSubStr function, and I noticed some behavior that doesn't seem correct.
I have an actor with a self text attribute called "text" that is initialized to 123456.
The actor has two displayText behaviors:
display text: textSubStr(self.text, 0, 5)
This displays 123456.
display text : textSubStr(self.text, 1, 5)
This displays 12345.
What the heck is going on? How can both of the displays start with 1?
Comments
textSubStr isn't really intended to be used with the 0th character of a string. What it seems to do is just add 1 to both numbers when a 0 is used. So instead of textSubStr(self.text,0,5) you're getting textSubStr(self.text,1,6).
What you seem to want is to be starting at the 1st character in the first example and the 2nd character in the second example:
textSubStr(self.text,1,5)
testSubStr(self.text,2,5)
The first would result in 12345
The second would result in 2345
The first number you provide is the first character that will displayed, the second number the second character.
Contact me for custom work - Expert GS developer with 15 years of GS experience - Skype: armelline.support
seems a bit fruity - I thought textSubStr was zero based anyway. But there is basically some kind of bug 0,3 gives the first FOUR characters as I would expect and 1,3 gives the first THREE. So it seems it can be kicked into a zero based way of thinking.
textSubStr does not expect to encounter 0s. It's presumably essentially string.sub from Lua. In Lua you can provide a negative which then refers to the end of the string.
GameSalad's implementation doesn't support negatives, but it does seem to pad the values you give it until both are positive numbers. 0,1 will give the first two characters (1,2). -1,1 will give the first three characters (1,3) etc.
Contact me for custom work - Expert GS developer with 15 years of GS experience - Skype: armelline.support
For more fun, you can actually hook into string.sub giving some cool advantages over textSubString:
self.String:sub(x) will provide the full string. If you don't give a second value, it will assume you mean the string length. So if I have the following string:
123456
And I use sub(3), I'll get 3456 as the result. This saves you from having to do textSubStr(3,textLength(string)).
If you want to count from the end of a string, you can. So sub(3,-1) will count from the final character in the string to the 3rd - so the result would be 3456. -2 will count from the second to last. So sub(3,-2) would give 345.
Contact me for custom work - Expert GS developer with 15 years of GS experience - Skype: armelline.support
This states that Lua strings are indexed starting at 1, not 0:
http://lua-users.org/wiki/StringLibraryTutorial
New to GameSalad? (FAQs) | Tutorials | Templates | Greenleaf Games | Educator & Certified GameSalad User
@Armelline oh so padding is administered equally ? 0,3 becomes 1,4
@tmann That appears to be the case when using textSubString, yes. You get tons more options with sub though!
Contact me for custom work - Expert GS developer with 15 years of GS experience - Skype: armelline.support
Is there any interest in a quick video about the hidden string manipulation capabilities of GameSalad? Things like...
There's nearly the full power of Lua's string manipulation available to us.
Contact me for custom work - Expert GS developer with 15 years of GS experience - Skype: armelline.support
@Armelline given the current state of the documentation I would say absolutely yes
Keep in mind that textSubString is utf8 aware and the built in lua string functions are not. Depending on the content of your strings, the built in functions can do the completely wrong thing if you aren't careful.
textSubString isn't too complicated, but it does expect your indices to be 1 based.
The parameters in the code are treated as a start index and end index inclusive, so textSubStr(1, 2) gives you two characters as expected, but textSubStr(0, 2) gives you three characters.
The reason is the number of characters to be extracted is endIndex - startIndex + 1, so 0 for the first parameter gives you an extra character because 2 - 1 + 1 = 2 and 2 - 0 + 1 = 3. If the first index is < 1 then the whole range is shifted so that the extraction starts at the first character.
Hope that helps a little.
Interesting!
If they work in creator, can they reasonably be expected to work on device?
Contact me for custom work - Expert GS developer with 15 years of GS experience - Skype: armelline.support
The engine is the same, so I would expect the same results. If you're not using characters that would span multiple bytes when converted to utf8 you shouldn't have any issues.
@Armelline Thanks for your answers and yes a video would be great! I'm specifically looking for a way to remove/replace the nth index of a string.
Another thing that I found odd, why is it that when you put numbers into a text attribute, you can still perform arithmetic operations on them as if they were a number attribute? Shouldn't you be unable to do that if it's a string?
Here's a demo that replaces the nth index of a string. To remove the nth index, make game.replacementChar a blank string. Let me know if you have any questions.
New to GameSalad? (FAQs) | Tutorials | Templates | Greenleaf Games | Educator & Certified GameSalad User
@tatiang already has you covered there, by the looks of it, so I'll not redo that!
This is to be expected. Most programming languages allow you to treat a string of numbers as a string. Unfortunately it doesn't work the other way, though - you can't directly manipulate an integer with string functions.
Contact me for custom work - Expert GS developer with 15 years of GS experience - Skype: armelline.support
I assume you mean " a string of numbers as a number"...?
Also thanks @tatiang, that's perfect.
Oops, yes! Well spotted!
Contact me for custom work - Expert GS developer with 15 years of GS experience - Skype: armelline.support
Necroing this post as I have a related problem.
I am using text substring to make sure only some characters (in my example 12) are shown in my input field -but as my app is sending the whole string (not just what is dispayed) to the backend, when I pull the data back in to the app, through a Loop over table, the whole string is there ie. 16 characters or whatever the user put in.
Is there a way to limit the data entry / submission of characters to 12, not just the display of characters?
@Rogue Anvil You can put your input buttons in a rule that says "If textLength(game.Input) <= 12 then allow button press".
That way the buttons will stop being active and allowing input when your maximum length is reached.
Contact me for custom work - Expert GS developer with 15 years of GS experience - Skype: armelline.support
@Armelline's suggestion is a good one. Another way would be to truncate the attribute value after it's entered:
Change attribute game.Input to textSubStr(game.Input,1,12).
New to GameSalad? (FAQs) | Tutorials | Templates | Greenleaf Games | Educator & Certified GameSalad User
@Armelline - cool fix I like your thinking!
@tatiang am a bit new to GS - where exactly would you have me implement your solution?
Right after the user inputs the value. So something like this:
[user inputs value e.g. with Keyboard Input or custom keyboard buttons]
Change attribute game.Input to textSubStr(game.Input,1,12).
I'd have to see your rules or pseudocode to know how you've set this up but that's the general order of things.
New to GameSalad? (FAQs) | Tutorials | Templates | Greenleaf Games | Educator & Certified GameSalad User
Here's a quick demo. Click the white square, then enter a phrase (e.g. "The quick brown fox jumps over a lazy dog.") and click Done. The truncated result will be displayed.
New to GameSalad? (FAQs) | Tutorials | Templates | Greenleaf Games | Educator & Certified GameSalad User
So I tried this... I also tried using the substr in the rule that changes the old saved name, but didn't work either.
Can you see anything from this?
Never mind I got it to work by looking into your example and forcing the attribute change when clicking the submit button. Thanks for the help!