Combining lists

Got a LiveCode personal license? Are you a beginner, hobbyist or educator that's new to LiveCode? This forum is the place to go for help getting started. Welcome!

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller

Post Reply
danielrr
Posts: 142
Joined: Mon Mar 04, 2013 4:03 pm

Combining lists

Post by danielrr » Mon Mar 04, 2013 4:33 pm

Hi, this is my first message to this forum. As a way of presentation I'll say that I am prety new to LiveCode (which I find terrific) but a long user of HyperCard and more recently of Python3. I purchased LiveCode long ago, but only when I heard it was going opencode I decided to give it a good try. The experience is being wonderful, although I have returned to the 6-hours-before-the-monitor old rutine…

My question is as follows: I can't find an obvious way to split and concatenate lists. I can build a function for that, but I was wandering if I am not missing something. With HC I used very powerful externals (from the blessed Rinaldi, Dumbar o Darthmouth collections) like VConcat, VSplit, etc.)

Say we have three lists of comma separated elements in three variables called lista, listb and listc:

LISTA: Italy, Spain, France
LISTB: Pizza, Paella, Escargots
LISTC: Chianti, Rioja, Burdeos

What is the fastest (built-in, if possible) way lo concatenate or combine the lists (other than building an ad-hoc function), so that I have [using something like concatenate (lista,listb,listc)]? I work with very long lists with different numbers of members (so that the number of parameters of the concatenate function is not known in advance) and speed is paramount

LIST X:
Italy, Pizza, Chianti
Spain, Paella, Rioja
France, Escargots, Burdeos

If this question is too trivial, please accept my apologies. Best wishes,

Daniel

magice
Posts: 457
Joined: Wed Mar 18, 2009 12:57 am

Re: Combining lists

Post by magice » Mon Mar 04, 2013 5:40 pm

Assuming that your lists are already in variables, then concatenate by doing the following

Code: Select all

put listA & listB & listC into tNewVariable
the new variable can be split as follows

Code: Select all

split tNewVariable by comma
That will turn the new variable into an array. You can then access each element of the array by bracketing the array element number. tNewVariable[1] tNewVariable[2] etc.
Of course you can name your variable what ever you want.

danielrr
Posts: 142
Joined: Mon Mar 04, 2013 4:03 pm

Re: Combining lists

Post by danielrr » Mon Mar 04, 2013 6:24 pm

Hi Magice,

Maybe I didn't make myself clear. If I do what wou are proposig

Code: Select all

put listA & listB & listC into tNewVariable
then I end with a new variable tNewVariable which is a concatenation of lists (i.e. A+B+C) but what I am looking for is a way to obtain a new list with as many columns as there are concatenated parameters, and in each row of the column the nth element of every list.

listA = 1,2,3,4
listB = A,B,C,D

Concatenated List= 1,A & return & 2,B & return 3,C
etc

sturgis
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 1685
Joined: Sat Feb 28, 2009 11:49 pm

Re: Combining lists

Post by sturgis » Mon Mar 04, 2013 6:53 pm

Heres a method that creates a numbered array out of the data.

First, do as magice said and truncate them together..

Code: Select all

put list1 & cr & list2 & cr & list3 into tTempList
Then cycle through the lines with for each, and each item on each line. (inside loop)

Code: Select all

on mouseUp
   put field 1 into tData -- where my test data is
   put true into tFirst -- mark that this is the first time through
   repeat for each line tLine in tData -- grab each line in turn
      put 1 into tItemCount -- start at item 1. Repeat this for each line.
      repeat for each item tItem in tLine -- repeat for each item of the current line
         if not tFirst then -- if this is not the first line, use comma separator otherwise don't
            put comma & tItem after tDataA[tItemCount] -- since this is NOT a first, put a comma and the next item from the line appended
         else
            put tItem into tDataA[tItemCount] -- if this IS the first time through, just put the data into the array element. 
            put false into tFirst -- set the first time flag to false
         end if
      add 1 to tItemCount -- add to the item count which increments the numeric index for the array.
      end repeat
   end repeat
end mouseUp

Leaves you with an array. If you really need it back into a flat file you can then loop through once more. (otherwise you can use it from the array itself)

Code: Select all

repeat for each key tKey in tArray
put tDataA[tKey] & cr after myVariable
end repeat
delete the last char of myVariable -- remove the extraneous cr
EDIT: I'm sure theres a better way, maybe doing magic with split and combine but my noggin just isn't up to it at the moment.

mwieder
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 3581
Joined: Mon Jan 22, 2007 7:36 am
Contact:

Re: Combining lists

Post by mwieder » Mon Mar 04, 2013 7:58 pm

Ah... you want a pivot function. Here's my take on it:

Code: Select all

    split listA by comma
    split listB by comma
    split listC by comma
    repeat for each key tCountry in listA
        put listA[tCountry], listB[tCountry], listC[tCountry] & cr after tNewList
    end repeat

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 4172
Joined: Sun Jan 07, 2007 9:12 pm

Re: Combining lists

Post by bn » Mon Mar 04, 2013 8:08 pm

Hi Daniel,

welcome to the forum.

The Hypercard way would be to make a repeat loop.

Code: Select all

repeat with i = 1 to the number of lines of list1
put line i of list1 & comma & line i of list2 & comma & line i of list3 & return after tCollect
end repeat
The problem with this is that Hypercard / LiveCode has to do a lot of counting. Each time around find out where line xxxx of listx is. This is perfectly alright for short lists.

But you made the point of having long lists and speed is very important.
Sturgis and magice proposed to use a array.

Here I attach a stack that generates 3 lists with 50000 lines each and combines the lists as columnar data resulting in a list of 50000 lines. One button uses arrays, the other the above mentioned repeat version.
Speed depends on your Hardware of course but using arrays in this case increases speed dramatically. It takes about 235 milliseconds to assemble the combined list with arrays and 71000 milliseconds using repeat as described above.

Have a look at the scripts and ask if something is not working/clear.
Combine3ListsAsColumns.livecode.zip
(1.73 KiB) Downloaded 253 times
Kind regards

Bernd

OK I goofed up since I assumed you had a return delimited list. But Mark Wieder put a comma version up.

And you could change the code of my stack easily to handle comma delimited lists instead of return delimited lists. Just use Mark split by comma code.

magice
Posts: 457
Joined: Wed Mar 18, 2009 12:57 am

Re: Combining lists

Post by magice » Mon Mar 04, 2013 8:20 pm

This is a simple example of how arrays work. Put this script in a button.

Code: Select all

on mouseUp
   put "cat, dog, pig" into List1
   put "feline, canine, porcine" into List2
   put "catfood, dogfood, peopleIDontLike" into List3
   
   split List1  by comma
   split List2 by comma
   split List3 by comma 
   
   put List1 into tArray[1]
   put List2 into tArray[2]
   put List3 into tArray[3]
   
   answer tArray[1][2], tArray[2][2], tArray[3][2]
end mouseUp
now play with the array number in the answer line to see how all the elements are referenced.
I may still be misunderstanding your intent, but I feel like the answer lies in an array.

sturgis
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 1685
Joined: Sat Feb 28, 2009 11:49 pm

Re: Combining lists

Post by sturgis » Mon Mar 04, 2013 9:41 pm

Actually, if the list is really long, and they're kept in fields and are comma delimited, the long lines in fields limitations become a problem, but most likely thats not how its beign done.

Not a big deal unless using a field for list storage.

jacque
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 7393
Joined: Sat Apr 08, 2006 8:31 pm
Contact:

Re: Combining lists

Post by jacque » Tue Mar 05, 2013 7:34 pm

A built-in way would be to concatenate the lists and then split by column:

Code: Select all

put listA & cr & listB & cr & listC into tVar
set the columndelimiter to comma
split tVar by column
Edit: to get it back out, you need to twiddle a little bit:

Code: Select all

put listA & cr & listB & cr & listC into tVar
set the columndelimiter to comma
split tVar by column
combine tVar by "{" -- you can use any char here
replace cr with comma in tVar
replace "{" with cr in tVar
Jacqueline Landman Gay | jacque at hyperactivesw dot com
HyperActive Software | http://www.hyperactivesw.com

Post Reply