This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
CCJJSax's profile picture

String.find() Return Single Number

Started by CCJJSax, 30 October 2013 - 06:44 PM
CCJJSax #1
Posted 30 October 2013 - 07:44 PM
I didn't know how to title this just right. But here is what's going on.


blah = [[slotNumb = 12
]]

string.find(blah[1], "=")

it will return "1010". This is expected. I know that it's supposed to return the first character and the last character. However, this isn't ideal for finding a single character like my "=". Is there an easy way to return just "10" from that?

Also I know I could use p1, p2 = string.find(slotNumb, "=") but I'm hoping for something that doesn't use a variable, I'm picky like that lol.
spdkils #2
Posted 30 October 2013 - 07:54 PM
well, you could convert it to a string, cut the length in 1/2, pull the 1/2 and convert it back tonumber all in one big ugly line!!!!
CCJJSax #3
Posted 30 October 2013 - 07:56 PM
well, you could convert it to a string, cut the length in 1/2, pull the 1/2 and convert it back tonumber all in one big ugly line!!!!

Yeah, I considered putting that in my I-know-I-could section I have, but I didn't because the p1, p2 = string.find(slotNumb, "=") is cleaner and easier as it is.
OReezy #4
Posted 30 October 2013 - 07:57 PM
Try adding a '?' after the '=' in string.find

Edit: I'm playing around with it some more and I'm not sure its doing what I thought it was doing
CCJJSax #5
Posted 30 October 2013 - 08:02 PM
Try adding a '?' after the '=' in string.find

Edit: I'm playing around with it some more and I'm not sure its doing what I thought it was doing

Well done sir. You win an imaginary cookie! Thanks :D/>

Edit: You're right, it's not doing what I thought it was after playing with it either. COOKIE REVOKED ;)/>
OReezy #6
Posted 30 October 2013 - 08:15 PM
COOKIE REVOKED ;)/>

Awww I tried! :P/>
ElvishJerricco #7
Posted 30 October 2013 - 08:15 PM
So you're wondering how to only get the first parameter? Lua drops all but the first return when a multiple return function call is in a larger expression. For example,


string.find(s, "=") + 1

returns only the first return, plus 1. The second return is forgotten. So to put a string.find call in a greater expression most easily, just surround it in superfluous parentheses.


print( ( string.find(s, "=") ) )
-- also,
print(string.find(s, "="), nil) -- the nil acts as a second parameter, not allowing more than one parameter to come out of the string.find call.

Of course this is only useful if you're trying to not return multiple values into a function call. But conventionally, it's not such a great idea to do things this way. I know it's kind of ugly to say r1, r2 = call(); dothing(r1); – forget r1 and r2 forever, but it's not as ugly as awkward syntax whose purpose is unclear. Plus you don't even have to do p2. Just use r1 = call() and the second return is dropped.
CCJJSax #8
Posted 30 October 2013 - 08:41 PM
So you're wondering how to only get the first parameter? Lua drops all but the first return when a multiple return function call is in a larger expression. For example,


string.find(s, "=") + 1

returns only the first return, plus 1. The second return is forgotten. So to put a string.find call in a greater expression most easily, just surround it in superfluous parentheses.


print( ( string.find(s, "=") ) )
-- also,
print(string.find(s, "="), nil) -- the nil acts as a second parameter, not allowing more than one parameter to come out of the string.find call.

Of course this is only useful if you're trying to not return multiple values into a function call. But conventionally, it's not such a great idea to do things this way. I know it's kind of ugly to say r1, r2 = call(); dothing(r1); – forget r1 and r2 forever, but it's not as ugly as awkward syntax whose purpose is unclear. Plus you don't even have to do p2. Just use r1 = call() and the second return is dropped.

I think this knowledge will help substantially with what I'm doing. Thank you!
spdkils #9
Posted 30 October 2013 - 11:09 PM
deleted…. I tried it in demo mode, and didn't work

http://www.lua.org/cgi-bin/demo
theoriginalbit #10
Posted 30 October 2013 - 11:11 PM
OP, the '?' that you were told to put in tells the function that it is an optional argument, so the return values would work the same, hence that suggestion not working.

Secondly you don't need to do

start, finish = string.find("hello = world", '=')
if you want the start you can just do

start = string.find("hello = world", '=')
if you want the end however you'd need to do it with both, however this is where most people use _ as the variable name to specify they don't care about that variable

_, finish = string.find("hello = world", '=')

As Elvish said when multiple return values are present in expressions it only uses the first unless the expression allows for the multiple values. This goes the same for conditionals too, for example we can check to see if '=' is in an input

write("Input some text with an = sign in it: ")
local input = read()
if input:find('=') then
  print("valid input")
else
  print("you suck at reading instructions! I told you to put an = in there!")
end

Of course this is only useful if you're trying to not return multiple values into a function call.
only vararg functions have this problem… for example

print(("hello = world"):find('=')) --# is a vararg function, accepts all the return values
print('\n', ("hello = world"):find('=')) --# is a vararg function, accepts all the return values
write(("hello = world"):find('=')) --# isn't a vararg, only accepts the first return value
then of course even varargs we can stop it like you did with the second parameter `nil`
ElvishJerricco #11
Posted 31 October 2013 - 06:23 AM
only vararg functions have this problem… for example

print(("hello = world"):find('=')) --# is a vararg function, accepts all the return values
print('\n', ("hello = world"):find('=')) --# is a vararg function, accepts all the return values
write(("hello = world"):find('=')) --# isn't a vararg, only accepts the first return value
then of course even varargs we can stop it like you did with the second parameter `nil`

It's not just vararg functions. It's any function whose number of parameters is greater than the index of argument the function call is in, as long as the function call is the last passed argument.


function func(a,b )
	b = b or defaultVal
	-- do something
end

func(s:find("="))

Whoops! You passed in a b argument when you only wanted to pass in a and have b be default.

As for when multiple return values are allowed in an expression, it's never unless the expression is either a … token or it's a function call that is unmodified by other expression mechanics and it is the last in a comma separated list of expressions being assigned to a sufficient amount of variables. Except function argument lists which take all arguments they can get by expanding the last argument if it's a function call to save maximum amount of returns and pass all of them to the function.