Let's say we have a variable "tData" that contains some lines, with each line being a tab-delimited list, with the first column being an ID.
(The "t" that starts the variable name is standard LiveCode convention to identify temporary variables. You don't have to follow that convention, but you'll see it a lot on the forum and in the documentation.)
Code: Select all
1 heather founder
42 mary engineer
3 john intern
2 pat CEO
5 bob accountant
But if we try to get the line for id #2, we get the wrong line: put line lineoffset(2, tdata) of tData into theLine -- returns line #2
Similarly, if any of the other columns contain the string we're searching for, we'll accidentally match the first of those lines as well.
There are various solutions to this problem.
(1) Prepend zeroes. When putting the data in the variable, prepend zeroes to all IDs less than a certain number, e.g. 001, 002, 003. Then match with: lineoffset(002 & tab, tData)
This won't accidentally match 42, and won't match any other line that might happen to use the phrase 002, because we're searching for only 002 followed by a tab.
(2) Match on the cr and a tab. The return character in LC is referenced by either "cr" or "return". So we could try: lineoffset(cr & 2 & tab, cr & tData). That ensures that we don't match the line that starts with 42. By including the tab in our search, we avoid matching lines that start with 21, 25, 28, etc. To ensure that we can match the first line, which doesn't have a return character before it, we prepend "cr &" to the text we're searching. That also solves the problem where the line number returned would be the line *before* the data we want (we match the line with the return character, which is the previous line): by adding the "cr" to the data we're searching for, we've increased the number of lines in the search target by 1. [thanks to klaus for the "cr &" trick.)
(3) Use LC's "filter" command. Filter returns only the stuff from a container that you want. If you don't put the result into a new container, it destroys data in the original container.
Code: Select all
filter lines of fld "data" matching "cat*" -- the field will be modified, with non-matching lines erased
filter items of tData matching "cat" into results -- original variable not modified; item must match "cat" exactly since we didn't use *
Code: Select all
filter lines of tdata matching ("2" &tab& "*") into tResults
Code: Select all
filter lines of tData with regex pattern "2\t" into tResults
(4) Loop through the lines. By looping through the lines, we can test for an exact match:
Code: Select all
put tExampleStringAbove into tContainer
put findLineOfId(2,tContainer) into lineNumber
function findLineOfId idNum,container
repeat with loopLineNum = 1 to the number of lines in container
if line loopLineNum of container begins with idNum & tab then
return loopLineNum
end if
end repeat
end findLineOfId
(5) Put the data into an associative array. An associative array is an array where the keys are strings rather than integers. For example:
put myArray["color"] = "blue"
We could write a function to loop the data, storing it into an associative array for future use.
Code: Select all
set the itemDelimiter to tab -- default is comma
repeat for each line theLine in tData
put item 2 of theLine into myArray[item 1 of theLine]["name"]
put item 3 of theLine into myArray[item 1 of theLine]["job"]
end repeat
put myArray[5]["name"] into tName
put myArray[4]["job"] into tJob
There are probably other ways to do this.