I'm looking for a more consise way to sort a block of objects. Where you can sort a block of blocks based on the numeric position of the values to compare, there's no such shorthand for comparing objects by a given field:
test-data: reduce [
object [name: "A" value: 1]
object [name: "B" value: 3]
object [name: "C" value: 2]
]
One solution would be to extend the native SORT function to accept a WORD! argument corresponding to the object field. However, that would require an update to the language and might take a little while to be accepted.
I've sketched out the following SORT-BY function that would take either a word (for the object field) or a block (an expression that is applied to the object):
sort-by: func [series [block!] comparator [block! word!]][
forskip series 2 [
insert series either word? comparator [
all [
in series/1 :comparator
get in series/1 :comparator
]
][
use [object] compose [
object: first series
(comparator)
]
]
]
sort/skip series 2
head forall series [remove series]
]
It's not ideal—it iterates through the block pulling the respective value from each object and adding it to the block; sorts the block; and removes the value again.
sort-by test-data 'value
sort-by test-data 'name
sort-by test-data [object/value]
sort-by test-data [sine 50 * object/value]
Any thoughts on the approach, particularly economy? Or even the need for such a function...
Obviously is lacking a descending/ascending switch—implied in future revision.