Peter M. Brigham pmbrig at gmail.com
Fri Oct 30 09:20:30 EDT 2015

While we're waiting for the Edinburgh team to implement possible solutions, you can use the lineoffsets() function that I have posted here in the past (included below). The function could be adjusted to return the text of the lines instead of the offset numbers, but probably then it should return an array. (Similar functions for itemoffsets() and wordoffsets() are fairly trivial.) The processing time for the function is fast enough that it's useful in most circumstances, even in very large texts, but in long repeat loops it will be a problem. So I would support engine/syntax changes to build something more efficient into the engine.

-- Peter

Peter M. Brigham
pmbrig at gmail.com


function lineOffsets str, pContainer, matchWhole
   -- returns a comma-delimited list of all the lineOffsets of str
   --    in pContainer
   -- if matchWhole = true then only whole lines are located
   --    else finds line matches everywhere str is part of a line in pContainer
   -- duplicates are stripped out
   -- note: to get the last lineOffset of a string in a container (often useful)
   --    use "item -1 of lineOffsets(...)"
   -- by Peter M. Brigham, pmbrig at gmail.com — freeware
   -- requires offsets()
   if matchWhole = empty then put false into matchWhole
   put offsets(str,pContainer) into offList
   if offList = "0" then return "0"
   repeat for each item i in offList
      put the number of lines of (char 1 to i of pContainer) into lineNbr
      if matchWhole then
         if line lineNbr of pContainer <> str then next repeat
      end if
      put 1 into A[lineNbr]
      -- using an array avoids duplicates
   end repeat
   put the keys of A into lineList
   sort lines of lineList ascending numeric
   replace cr with comma in lineList
   return lineList
end lineOffsets

function offsets str, pContainer
   -- returns a comma-delimited list of all the offsets of str in pContainer
   -- returns 0 if not found
   -- note: offsets("xx","xxxxxx") returns "1,3,5" not "1,2,3,4,5"
   --     ie, overlapping offsets are not counted
   -- note: to get the last occurrence of a string in a container (often useful)
   --     use "item -1 of offsets(...)"
   -- by Peter M. Brigham, pmbrig at gmail.com — freeware
   if str is not in pContainer then return 0
   put 0 into startPoint
      put offset(str,pContainer,startPoint) into thisOffset
      if thisOffset = 0 then exit repeat
      add thisOffset to startPoint
      put startPoint & comma after offsetList
      add length(str)-1 to startPoint
   end repeat
   return item 1 to -1 of offsetList -- delete trailing comma
end offsets

On Oct 29, 2015, at 1:11 PM, Ben Rubinstein wrote:

> On 29/10/2015 15:47, Richard Gaskin wrote:
>> Like "lineOffset", "lineAtOffset" would take the same arguments and
>> operate similarly, but rather than returning the number of the matching
>> line it would return the text of that line.
> >
> > Questions for you folks:
> >
> > 1. Is this as useful as I think it might be?
> >
> > 2....
> >
> > 3. Is this worth submitting to the request queue?
> My £0.02 for what they're worth:
> Of course this could be useful occasionally - but I'm not sure the value outweighs the cost - not so much the cost of implementation, as the cost of adding more words to the language.
> In code, it saves a single line.
> In efficiency, I grant there's a cost; but it seems to me that if the cost was high (i.e. you're searching in a really long piece of text, and you're doing it a very large number of times) then you could choose to mitigate that cost in various ways (e.g. doing split to get an array indexed by line number, or (depending on your situation) doing "offset" instead of line offset, and then taking a chunk starting sufficiently before the found character position and doing "lineoffset" on that...
> But mainly, I'm agin this proposal because, if there were to be changes to the offset suite of functions, I'd much rather that effort was spent on making them work backwards. It's fast and simple to do offset, lineoffset, etc to find the first occurrence of a fragment, or to walk 'forward' through the occurrences of a fragment; but it's neither fast nor simple to get the last occurrence, or to walk backwards through the occurences.
> There's an inconsistency here - LC makes it as easy to ask for the last item, or the third line from the end, as it does the first item, or the third line.  But the *offset functions only work in one direction.
> Also note that implementing the backwards offsets needn't (I think) require adding any new keywords, because we can use the skip parameter with a negative number.
> Sorry to hijack your thread!
> Ben
> _______________________________________________
> use-livecode mailing list
> use-livecode at lists.runrev.com
> Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
> http://lists.runrev.com/mailman/listinfo/use-livecode

More information about the use-livecode mailing list