HiveBrain v1.2.0
Get Started
← Back to all entries
snippetMinor

'Sort By' Function for Rebol

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
rebolsortfunctionfor

Problem

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.

Solution

Any reason you can't use the SORTs /COMPARE refinement here?

Here is a working example of sort-by that uses it:

sort-by: function [
series [block!]
comparator [block! word!]
][
sort/compare series func [
a b] either word? comparator [
[
a/:comparator

Context

StackExchange Code Review Q#71891, answer score: 3

Revisions (0)

No revisions yet.