Can a function return two values?

Anything beyond the basics in using the LiveCode language. Share your handlers, functions and magic here.

Moderators: Klaus, FourthWorld, heatherlaine, robinmiller, kevinmiller

kaveh1000
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 288
Joined: Sun Dec 18, 2011 7:23 pm
Location: London
Contact:

Can a function return two values?

Post by kaveh1000 » Wed Jan 30, 2019 11:49 pm

I have a (long) piece of text that I want to split using certain criteria. I want a function to do the splitting, but I then want the two pieces of text returned, so simplistically I want to say:

Code: Select all

function split_it pText
[...do some magic to get tText1 and tText2...]
return tText1
return tText2
which is of course not possible. I could say:

Code: Select all

function split_it pText
[...do some magic to get tText1 and tText2...]
return tText1, tText2
using comma as a delimiter. But of course there are commas in the text. I could then use a unique string as the delimiter, but it gets increasingly messy.

I am sure I am missing something simple, so look forward to slamming my forehead at the solution. ;-)

Thanks.

Kaveh
Kaveh

Klaus
Posts: 11110
Joined: Sat Apr 08, 2006 8:41 am
Location: Germany
Contact:

Re: Can a function return two values?

Post by Klaus » Thu Jan 31, 2019 12:27 am

The magic word is ARRAY! 8)

Code: Select all

...
put tText1 into tArray[1]
put tText2 into tArray[2]
return tArray
...

kaveh1000
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 288
Joined: Sun Dec 18, 2011 7:23 pm
Location: London
Contact:

Re: Can a function return two values?

Post by kaveh1000 » Thu Jan 31, 2019 12:54 am

Thank you sir! I must get into using arrays. :-) Great.
Kaveh

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 6116
Joined: Wed May 06, 2009 2:28 pm
Location: New York, NY

Re: Can a function return two values?

Post by dunbarx » Thu Jan 31, 2019 3:16 am

Klaus' array is compact and modern.

But in more basic LC-ese you might think of inserting an unprintable character at the break point. Then you can use the itemDelimiter to separate the text. So if you had a large body of text in a variable "longText", you could:

Code: Select all

on mouseUp
  set the itemDel to numToChar(202) --my favorite
  put trunc(the length of longText / 2) into tMiddle -- about the middle of any string
  put numToChar(202) after char tMiddle of longText
  put item 1 of longText into firstPortion --about half the string
  put item 2 of longText into secondPortion --the other half
  --do whatever here with your two halves
end mouseUp
Reassembling is straightForward. And when you separate longText using an item, the item itself is not included in either portion of the resulting two strings. Note that you do not NEED to use an unprintable character, anything above 127 might do, but strange extended ASCII chars to oftentimes work themselves into text.

I mention all this because I think it is important to play with LC string functionality at a low level; it helps with the fancier stuff later on.

Craig Newman
Last edited by dunbarx on Thu Jan 31, 2019 3:27 am, edited 1 time in total.

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 6116
Joined: Wed May 06, 2009 2:28 pm
Location: New York, NY

Re: Can a function return two values?

Post by dunbarx » Thu Jan 31, 2019 3:26 am

It just occurred to me that you wanted a function. Again, given a string,

Code: Select all

on mouseUp
      put "1234567890" into longText
   answer splitText(longText)
end mouseUp

function splitText tText
   set the itemDel to numToChar(202)
   put trunc(the length of tText / 2) into tMiddle -- about the middle of any string
   put numToChar(202) after char tMiddle of tText
   return item 1 of tText  & return & item 2 of tText
end splitText
Craig

FourthWorld
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 6791
Joined: Sat Apr 08, 2006 7:05 am
Location: Los Angeles
Contact:

Re: Can a function return two values?

Post by FourthWorld » Thu Jan 31, 2019 3:28 am

I don't know how well this will fit your situation, but you can pass in variables by reference and they'll change the values in the calling handler automatically for you.
Richard Gaskin
Community volunteer LiveCode Community Liaison

LiveCode development, training, and consulting services: Fourth World Systems: http://FourthWorld.com
LiveCode User Group on Facebook : http://FaceBook.com/groups/LiveCodeUsers/

mwieder
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 2820
Joined: Mon Jan 22, 2007 7:36 am
Location: Berkeley, CA, US
Contact:

Re: Can a function return two values?

Post by mwieder » Thu Jan 31, 2019 5:07 am

I also have some functions that just return a comma-separated pair of numbers. As in

Code: Select all

function someFunction
local tWidth, tHeight

  -- do something here
  return tWidth,tHeight
end someFunction

kaveh1000
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 288
Joined: Sun Dec 18, 2011 7:23 pm
Location: London
Contact:

Re: Can a function return two values?

Post by kaveh1000 » Thu Jan 31, 2019 8:53 am

Thank you all.

@Mark, your solution is what I tried first and useful for values, but here I am dealing with long text that includes commas, so need an unusual character for delimiter.

@Craig, what is char 202? I am dealing with 3rd party text. is there a chance that char would be in the text I am passing to the function?
Kaveh

bogs
Posts: 3706
Joined: Sat Feb 25, 2017 10:45 pm

Re: Can a function return two values?

Post by bogs » Thu Jan 31, 2019 11:07 am

dunbarx wrote:
Thu Jan 31, 2019 3:16 am
Klaus' array is compact and modern.
But in more basic LC-ese you might think of inserting an unprintable character at the break point. Then you can use the itemDelimiter to separate the text. So if you had a large body of text in a variable "longText", you could:

Code: Select all

on mouseUp
  set the itemDel to numToChar(202) --my favorite
  put trunc(the length of longText / 2) into tMiddle -- about the middle of any string
  put numToChar(202) after char tMiddle of longText
  put item 1 of longText into firstPortion --about half the string
  put item 2 of longText into secondPortion --the other half
  --do whatever here with your two halves
end mouseUp
Reassembling is straightForward. And when you separate longText using an item, the item itself is not included in either portion of the resulting two strings. Note that you do not NEED to use an unprintable character, anything above 127 might do, but strange extended ASCII chars to oftentimes work themselves into text.
I mention all this because I think it is important to play with LC string functionality at a low level; it helps with the fancier stuff later on.
Craig Newman
You might want a non type-able non displaying character in something like that, like null.
Lc Dictionary wrote: null
Type: constant
See Also: space Constant, constant Command
Introduced: 2.0
Platforms: Desktop, Server, Web and Mobile
Summary:
Equivalent to the null character (ASCII zero).
Examples:
read from file modem: until null
Use the null constant as an easier-to-read substitute for numToChar(0).
Comments:
The null constant is needed because you can't type the character it represents in a script.
I love null from the days where I wrote batch scripts in dos, because I often used your favorite ctn(202) as part of the *display design. I also think it is what csv files should have used (cnv?) :D

@Kaveh,
You can find a chart of all ascii text in any search, like this result.
In this case, ASCII code 202 = ╩ ( Box drawing character double line horizontal and up )

*Display design - before real gui desktops, it was all crafted at the CLI
Image
Last edited by bogs on Thu Jan 31, 2019 11:50 am, edited 1 time in total.
Image

Thierry
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 642
Joined: Wed Nov 22, 2006 3:42 pm
Location: France
Contact:

Re: Can a function return two values?

Post by Thierry » Thu Jan 31, 2019 11:21 am

Hi kaveh,

Never forget that LiveCode is sooooo flexible...

So, here is one way by setting your own delimiter:

Code: Select all

local kaveh_delimiter = "__KAVEH__"

function split_it pText
   // ...do some magic to get tText1 and tText2
   put char 1 to 10 of pText into tText1
   put char 11 to -1 of pText into tText2
   
   return tText1 & kaveh_delimiter & tText2
end split_it
and use it this way:

Code: Select all

on test
   local R
   put split_it( "1234567890abcdef") into R
   set the itemdel to kaveh_delimiter
   // check results:
   answer item 1 of R
   answer item 2 of R
end test
or another one which I prefer:

Code: Select all

command split_it2 pText, @tText1, @tText2
   // ...do some magic to get tText1 and tText2
   put char 1 to 10 of pText into tText1
   put char 11 to -1 of pText into tText2
end split_it2

Code: Select all

on test
   local R1, R2
   split_it2 "1234567890abcdef", R1, R2
   // check results:
   answer R1
   answer R2
end test
HTH,
Thierry
Thierry Douez - https://sunny-tdz.com
Pourquoi tant de notes lorsqu'il suffit de jouer les plus belles... [Barbara]

kaveh1000
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 288
Joined: Sun Dec 18, 2011 7:23 pm
Location: London
Contact:

Re: Can a function return two values?

Post by kaveh1000 » Thu Jan 31, 2019 2:37 pm

Thank you all for these gems. And Thierry, yes, I love LiveCode because of its flexibility and the fact that we can be so creative in it. One of my favorite discoveries is using a multi-character LineDelimiter. Wonderful concept...

I am going to study the replies very carefully and see which method works best.
Kaveh

richmond62
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 3461
Joined: Fri Feb 19, 2010 10:17 am
Location: Bulgaria

Re: Can a function return two values?

Post by richmond62 » Thu Jan 31, 2019 3:42 pm

To answer the initial question just go and work out the square root of 4. 8)

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 6116
Joined: Wed May 06, 2009 2:28 pm
Location: New York, NY

Re: Can a function return two values?

Post by dunbarx » Thu Jan 31, 2019 3:46 pm

The ability to set the itemDel to multiple chars is cool indeed.

When I suggested ASCII 202, it was just because that char is VERY unlikely to appear in any conceivable text. But since multiple chars can now be an item, you could also use "ZZZZZZZZ", and that, too, is unlikely to appear in any conceivable text.

so.

Code: Select all

on mouseUp
      put "1234567890" into longText
   answer splitText(longText)
end mouseUp

function splitText tText
   set the itemDel to "ZZZZZZZZ"
   put trunc(the length of tText / 2) into tMiddle -- about the middle of any string
   put "ZZZZZZZZ"  after char tMiddle of tText
   return item 1 of tText  & return & item 2 of tText
end splitText
Craig

kaveh1000
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 288
Joined: Sun Dec 18, 2011 7:23 pm
Location: London
Contact:

Re: Can a function return two values?

Post by kaveh1000 » Thu Jan 31, 2019 3:50 pm

Well I am not going to take a risk with ZZZZZ. I tell you what, I have actually been using the millisecs as the itemdelimiter. So it is generated on the fly and pretty foolproof. ;-)
Kaveh

mwieder
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 2820
Joined: Mon Jan 22, 2007 7:36 am
Location: Berkeley, CA, US
Contact:

Re: Can a function return two values?

Post by mwieder » Thu Jan 31, 2019 5:05 pm

I regularly use numtochar(3) as a delimiter when I need something that is guaranteed to be unprintable.

Post Reply

Return to “Talking LiveCode”