[REBOL] REP: Adding /SKIP refinement to FIND and SELECT
From: joel::neely::fedex::com at: 31-Oct-2000 8:48
Later versions of REBOL do have find/skip and select/skip
Shows the power of the Mailing list!
Adding /SKIP refinement to FIND and SELECT REBOL Enhancement Proposal: REP Version: 1.0.0 Date: 31-Oct-2000 Author: Joel Neely ([joel--neely--fedex--com]) I propose as a possible REBOL enhancement that the /skip refinement be added to FIND and SELECT for the purpose of processing grouped data in a consistent manner with the current behavior of SORT/SKIP , FORALL [...] , and FORSKIP . ===Background The REBOL block! , list! and hash! types provide a highly flexible scheme for managing collections of values. Most of the functions that operate on these collections allow the user to regard a collection either as containing individual values: students: ["Tom" "Dick" "Harry" "Jane" "Sally" "Spot"] sort students foreach student students [prin [student " "]] print "" -> Dick Harry Jane Sally Spot Tom roll: sort [ "Tom" "Dick" "Harry" "Jane" "Sally" "Spot" "Billy" "Elvis" ] foreach student roll [ if not find students student [ print [student "was absent"] ] ] -> Billy was absent -> Elvis was absent or as containing groups of related values. emps: [ 845 "Joe Doaks" #555-1845 401 "Jane Zoe" #555-1401 123 "John Doe" #555-1123 ] forskip emps 3 [ prin [emps/1 emps/2 " "] ] print "" emps: head emps -> 845 Joe Doaks 401 Jane Zoe 123 John Doe sort/skip emps 3 foreach [id name phone] emps [ prin [name ":" phone " "] ] print "" -> John Doe : 555-1123 Jane Zoe : 555-1401 Joe Doaks : 555-1845 ===Limitations The current implementations of FIND and SELECT lack the ability to deal with related-group blocks, instead examining each value in the searched block individually (until success or end of block). This limitation has the following consequences: 1) Additional workaround code is required when searching blocks of related-group values. Such code must be written, debugged, maintained, and can have a higher run-time cost than native code. For example (one of many possible approaches): find-emp: func [id [integer!] /local temp result] [ temp: head emps result: copy  forskip temp 3 [ if id = temp/1 [result: copy/part temp 3 break] ] result ] find-emp 401 == [401 "Jane Zoe" #555-1401] find-emp 999 ==  2) There is the risk of inadvertent "aliasing" in one of the most common applications of SELECT, looking up a key value in a block that stores name-and-value pairs. If a searched-for key is preceded by another instance of the same data value, but in the "value" position in a name-and-value pair, the desired key will not be found. For example: shoe-inventory: [ 6 8 7 12 8 9 9 6 10 4 ] size: 8 select shoe-inventory size == 7 find shoe-inventory size == [8 7 12 8 9 9 6 10 4] ===Proposal Extend the definition of FIND and SELECT to include the /SKIP refinement, which would modify the behavior of FIND and SELECT (i.e., in a manner consistent with that of SORT/SKIP) so that find/skip shoe-inventory 9 2 would evaluate to == [9 6 10 4] by beginning the search at the current position and incrementing the examined position by 2 for each iteration of the search loop. Furthermore, as SELECT is already defined as returning the value that corresponds to a found key, it is proposed that SELECT/SKIP consider the refinement's skip length argument, and return a block of values of the appropriate length (one less than the skip length) so that select/skip emp 401 3 would return ["Jane Zoe" #555-1401] as that is the remainder of the 3-element group SELECTed by a key value of 401 in the employee block. It might be argued that asking SELECT/SKIP to return a block is inconsistent with the current behavior of returning the next value after a found key. However, the current meaning of /SKIP for other existing functions is that the block should be considered as groups of data, rather than as individual, isolated values. As the meaning of select the-block the-key may be stated as "retrieve the value from the-block associated with the-key" (note the singular), it seems most natural to define the meaning of select/skip the-grouped-block the-key group-length as being "retrieve the group of values from the-grouped-block associated with the-key". As the resulting values (plural) would include all data but the key, the result would contain group-length - 1 elements. ### REBOL  do/args %makespec.r %rep.txt