REBOL [
    Title: "Count unique items"
    Purpose: {A specific helper function for a specific project.
    Given a block of strings, sorted, count the numbers of each
    of the unique values.  Return the result in a block.}
]

;; [---------------------------------------------------------------------------]
;; [ Given a block of strings, many of which are the same, produce counts      ]
;; [ of the same values.  In other words, if the input is this:                ]
;; [ [ A A A B B B B C C C C ] (The values are strings)                        ]
;; [ Return a block that looks like this:                                      ]
;; [ [ [A 3] [B 4] [C 4] ]                                                     ]
;; [ Yes, believe it or not, I actually had a use for this.                    ]
;; [---------------------------------------------------------------------------]

COUNT-UNIQUE: func [
    VALS 
    /local CRNTVAL COUNTER TOTAL RESULT
] [
    CRNTVAL: copy first VALS
    COUNTER: 0
    RESULT: copy []
    foreach VAL VALS [
        either equal? VAL CRNTVAL [
            COUNTER: COUNTER + 1
        ] [
            TOTAL: copy []
            append TOTAL CRNTVAL
            append TOTAL COUNTER
            append/only RESULT TOTAL
            COUNTER: 1
            CRNTVAL: copy VAL
        ]
    ]
    TOTAL: copy []
    append TOTAL CRNTVAL
    append TOTAL COUNTER
    append/only RESULT TOTAL
    return RESULT 
]

;;Uncomment to test
;print mold COUNT-UNIQUE [
;    "A"
;    "B" "B"
;    "C" "C" "C"
;    "D" "D" "D" "D"
;    "E" "E" "E" "E" "E"
;]
;halt