Re: foreach routine
- Posted by Derek Parnell <ddparnell at bigpond.com> Dec 21, 2006
- 665 views
duke normandin wrote: > > Hi... > > Where are we at on this issue? Here is a first cut at an interim solution...
-- foreach.e -- Extended version. Covers the full functionality. --/func every_item(pTheList, pRID, pData, pStart, pEnd, pSpan) --/desc Process each specified item in the list --/ret SEQUENCE: If no errors, a 4-element sequence; -- [1] = 0 (zero) -- [2] = 0 (if pRID sees each item) -- = integer (whatever pRID returned to end the processing) -- [3] = The index of the last item processed. -- [4] = The (possibly updated) list. -- If errors, a 2-element sequence; -- [1] = Error code: -- 1 => The supplied low index is < 1 -- 2 => The supplied low index is > list length -- 3 => The supplied high index is < 1 -- 4 => The supplied high index is > list length -- 5 => The supplied routine id is invalid -- [2] = The parameter in error. -- -- This function calls the routine id /i(pRID) for each of the items -- requested in the list /i(pTheList). The range and direction is -- specified by /i(pStart) and /i(pEnd). /i(pStart) is the index -- of the first item to be processed and /i(pEnd) is the index -- of the last item to be processed. If /i(pStart) is higher than -- /i(pEnd) then the items are processed in right-to-left order -- otherwise they are processed in left-to-right order. /n -- -- The /i(pSpan) parameter specifies the 'gap' between successive -- items to be processed. To process each item use 1 as the span, to -- process every second item use 2, etc... /n -- -- The /i(pRID) parameter is a routine id of a caller defined function -- which is called for each item processed. It is passed three parameters: -- [1] => The index of the item being processed. -- [2] => The value of the item being processed. -- [3] => The /i(pData) parameter. This can be any object. -- The routine must return either a single integer or a one-element -- sequence. If it returns a 0 (zero) then next item is processed. If -- it returns a non-zero integer, the processing of items is stopped. -- If it returns a sequence, the first element is used to replace the -- item just processed in the list. -- -- Example: --/code -- sequence res -- function showit(integer pIdx, object pItem, object pExtra) -- printf(1, "%d: %s\n", {pIdx, pItem}) -- if pItem = pExtra then return 1 end if -- return {pItem - ('A' - 'a')} -- end function -- -- res = every_item("ABCDEF", routine_id("showit"), 'D', 2, 5, 1) -- printf(1, "%d %d %d %s\n", res) --/endcode ---------------------------------------------------------- global function every_item(sequence pTheList, integer pRID, object pData, integer pStart, integer pEnd, integer pSpan) ---------------------------------------------------------- integer lDir object lRes integer lLastI integer lLow integer lHigh if length(pTheList) = 0 then return {0,0,0, pTheList} end if if pStart > pEnd then lDir = -1 lLow = pEnd lHigh = pStart else lDir = 1 lHigh = pEnd lLow = pStart end if if lLow < 1 then return {1, lLow} end if if lLow > length(pTheList) then return {2, lLow} end if if lHigh < 1 then return {3, lHigh} end if if lHigh > length(pTheList) then return {4, lHigh} end if if pRID < 0 then return {5, pRID} end if lRes = 0 for i = pStart to pEnd by lDir * pSpan do lLastI = i lRes = call_func(pRID, {i, pTheList[i], pData}) if integer(lRes) then if lRes != 0 then exit end if else pTheList[i] = lRes[1] end if end for return {0, lRes, lLastI, pTheList} end function --/func foreach(pTheList, pRID) --/desc Process every item in the list, from left to right. --/ret SEQUENCE: If no errors, a 4-element sequence; -- [1] = 0 (zero) -- [2] = 0 (if pRID sees each item) -- = integer (whatever pRID returned to end the processing) -- [3] = The index of the last item processed. -- [4] = The (possibly updated) list. -- If errors, a 2-element sequence; -- [1] = 5 (The supplied routine id is invalid) -- [2] = The pRID value. -- -- This function calls the routine id /i(pRID) for each of the items -- in the list /i(pTheList). They are processed in left-to-right order. /n -- -- The /i(pRID) parameter is a routine id of a caller defined function -- which is called for each item processed. It is passed three parameters: -- [1] => The index of the item being processed. -- [2] => The value of the item being processed. -- [3] => 0 -- The routine must return either a single integer or a one-element -- sequence. If it returns a 0 (zero) then next item is processed. If -- it returns a non-zero integer, the processing of items is stopped. -- If it returns a sequence, the first element is used to replace the -- item just processed in the list. -- -- Example: --/code -- sequence res -- function showit(integer pIdx, object pItem, object pExtra) -- printf(1, "%d: %s\n", {pIdx, pItem}) -- if pItem = 'D' then return 1 end if -- return {pItem - ('A' - 'a')} -- end function -- -- res = foreach("ABCDEF", routine_id("showit")) -- printf(1, "%d %d %d %s\n", res) --/endcode ---------------------------------------------------------- global function foreach(sequence pTheList, integer pRID) ---------------------------------------------------------- return every_item(pTheList, pRID, 0, 1, length(pTheList), 1) end function --/func foreach_reverse(pTheList, pRID) --/desc Process every item in the list, from right to left. --/ret SEQUENCE: If no errors, a 4-element sequence; -- [1] = 0 (zero) -- [2] = 0 (if pRID sees each item) -- = integer (whatever pRID returned to end the processing) -- [3] = The index of the last item processed. -- [4] = The (possibly updated) list. -- If errors, a 2-element sequence; -- [1] = 5 (The supplied routine id is invalid) -- [2] = The pRID value. -- -- This function calls the routine id /i(pRID) for each of the items -- in the list /i(pTheList). They are processed in right-to-left order. /n -- -- The /i(pRID) parameter is a routine id of a caller defined function -- which is called for each item processed. It is passed three parameters: -- [1] => The index of the item being processed. -- [2] => The value of the item being processed. -- [3] => 0 -- The routine must return either a single integer or a one-element -- sequence. If it returns a 0 (zero) then next item is processed. If -- it returns a non-zero integer, the processing of items is stopped. -- If it returns a sequence, the first element is used to replace the -- item just processed in the list. -- -- Example: --/code -- sequence res -- function showit(integer pIdx, object pItem, object pExtra) -- printf(1, "%d: %s\n", {pIdx, pItem}) -- if pItem = 'D' then return 1 end if -- return {pItem - ('A' - 'a')} -- end function -- -- res = foreach_reverse("ABCDEF", routine_id("showit")) -- printf(1, "%d %d %d %s\n", res) --/endcode ---------------------------------------------------------- global function foreach_reverse(sequence pTheList, integer pRID) ---------------------------------------------------------- return every_item(pTheList, pRID, 0, length(pTheList), 1, 1) end function
-- Derek Parnell Melbourne, Australia Skype name: derek.j.parnell