In Lua, can I easily select the Nth result without custom functions?
Asked Answered
H

3

5

Suppose I am inserting a string into a table as follows:

table.insert(tbl, mystring)

and that mystring is generated by replacing all occurrences of "a" with "b" in input:

mystring = string.gsub(input, "a", "b")

The obvious way to combine the two into one statement doesn't work, because gsub returns two results:

table.insert(tbl, string.gsub(input, "a", "b"))  -- error!
-- (second result of gsub is passed into table.insert)

which, I suppose, is the price paid for supporting multiple return values. The question is, is there a standard, built-in way to select just the first return value? When I found select I thought that was exactly what it did, but alas, it actually selects all results from N onwards, and so doesn't help in this scenario.

Now I know I can define my own select as follows:

function select1(n, ...)
  return arg[n]
end

table.insert(tbl, select1(1, string.gsub(input, "a", "b")))

but this doesn't look right, since I'd expect a built-in way of doing this.

So, am I missing some built-in construct? If not, do Lua developers tend to use a separate variable to extract the correct argument or write their own select1 functions?

Hourigan answered 24/4, 2010 at 14:22 Comment(0)
P
13

You can surround the expression by parentheses:

table.insert(tbl, (string.gsub(input, "a", "b")))

This will select only the first result.

To get the nth result, you can use select and surround it by parentheses:

func1( (select(n, func2())) )
Phyllys answered 24/4, 2010 at 14:30 Comment(6)
Thanks! I bet I will eventually run into the same situation wanting only the second result - what options do I have then?Hourigan
@romkyns: Updated my post to answer. Though your select1 function may be more readable.Phyllys
I like to use dummies for this, i.e. _,_,_,fourthVal,_ = giveMeFive() I find it more readable that way.Eurhythmic
@fbcocq: Yes, but the question for for an alternative way to that: It specifically asked how to avoid the assignment and do it in one statement. Also, select is needed when the value of n isn't known in advance.Phyllys
surround it by parentheses why is that needed?Parisparish
@Mvorisek Surrounding a function call that returns multiple values by parentheses will choose only the first returned result. If you're asking about the select call, the parentheses are needed because select returns multiple values.Phyllys
T
6

In one line: ({ funct(args) })[n] would return the n'th result without declaring any named variables.

Threecornered answered 15/9, 2013 at 14:14 Comment(0)
E
5

Putting an expression into parentheses like this:

table.insert(tbl, (string.gsub(input, "a", "b")))

will force one return value. Or you could catch them both like this:

str,cnt = string.gsub(input, "a", "b")
table.insert(tbl, str)

or even better, dummy catch it to save a variable:

str,_ = string.gsub(input, "a", "b")
table.insert(tbl, str)
Eurhythmic answered 24/4, 2010 at 14:31 Comment(2)
There is no reason to assign into two variables here. You can just assign one variable and the second value will be discarded, as shown in the beginning of the question.Phyllys
Just demonstrating a way to deal with multiple return values besides select, it's sometimes hard to keep track of return value adjustments in huge nested calls.Eurhythmic

© 2022 - 2024 — McMap. All rights reserved.