[REBOL] REP: Adding /SKIP refinement to FIND and SELECT
From: joel::neely::fedex::com at: 31-Oct-2000 8:48
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
Librarian comment
Later versions of REBOL do have find/skip and select/skip
Shows the power of the Mailing list!