std.sort
std.sort holds the array algorithms — ordering, transforming, and querying.
For sequence generation and slicing (range, chunk, take/drop, set ops)
see std.seq.
Many std.sort functions are also available as pipes on arrays directly —
sorter versions that mutate the receiver, e.g. arr:sort(), arr:map(fn),
arr:filter(fn) (see Pipes). The forms below
call them as pure functions (std.sort.sort(arr)), which return a new array.
Reference
sort(array[, comparator]) // ascending; comparator(a, b) returns true if a < b
sort_by(array, key) // sort objects by a string key
reverse(array)
shuffle(array)
unique(array) // remove duplicates, preserve order
flatten(array) // flatten nested arrays
slice(array, start[, end]) // end is exclusive
concat(array...) // join any number of arrays
fill(array, value[, start[, end]])
zip(array...)
every(array, predicate) // all elements pass?
some(array, predicate) // any element passes?
map(array, fn)
filter(array, predicate)
reduce(array, fn[, init])
find(array, predicate) // first matching VALUE, or null
find_index(array, predicate)// first matching INDEX, or -1
find_all(collection, value) // all indices (array) or keys (object) matching
Predicates are functions fn(element) { ... }; the sort comparator is
fn(a, b) { ... }.
Ordering
std.sort.sort([3, 1, 2]) // [1, 2, 3] (ascending)
std.sort.sort([3, 1, 2], fn(a, b) { return a > b }) // [3, 2, 1] descending
std.sort.reverse([1, 2, 3]) // [3, 2, 1]
sort_by orders an array of objects by one of their string keys — great for
sorting records:
var people = [
{name: "Bob", age: 40},
{name: "Ann", age: 30},
{name: "Cal", age: 35},
]
var byName = std.sort.sort_by(people, "name")
print(byName[0].name, byName[1].name, byName[2].name) // Ann Bob Cal
var byAge = std.sort.sort_by(people, "age")
print(byAge[0].age, byAge[1].age, byAge[2].age) // 30 35 40
The same operations run as pipes on the receiver:
var arr = [3, 1, 2]
arr:sort() // arr is now [1, 2, 3]
print(arr)
Deduplicate and reshape
std.sort.unique([3, 1, 3, 2, 1, 3]) // [3, 1, 2] (first-occurrence order)
std.sort.flatten([1, [2, 3], [4, [5, 6]]]) // [1, 2, 3, 4, 5, 6] (recursive)
std.sort.concat([1, 2], [3, 4], [5]) // [1, 2, 3, 4, 5]
std.sort.slice([0, 1, 2, 3, 4], 1, 3) // [1, 2] (end exclusive)
std.sort.fill([0, 0, 0], 7, 1, 2) // [0, 7, 0] (range: 1..<2)
std.sort.zip([1, 2, 3], ["a", "b", "c"])
// [[1, "a"], [2, "b"], [3, "c"]]
zip pairs up elements positionally and is handy for building records from
parallel arrays:
var names = ["Ann", "Bob"]
var scores = [88, 92]
var rows = std.sort.map(std.sort.zip(names, scores),
fn(p) { return {name: p[0], score: p[1]} })
print(rows[0]) // {"name": "Ann", "score": 88}
Transforming with map / filter / reduce
map applies a function to every element. filter keeps only the elements for
which the predicate is truthy:
var nums = [1, 2, 3]
std.sort.map(nums, fn(x) { return x * x }) // [1, 4, 9]
std.sort.filter(nums, fn(x) { return x % 2 == 0 }) // [2]
// pipe form
var evens = [1, 2, 3, 4]
var onlyEven = evens:filter(fn(x) { return x % 2 == 0 })
print(onlyEven) // [2, 4]
reduce folds the array into a single value. With no init, the first
element is the starting accumulator and the fold runs from the second; with
init, it starts from that value:
std.sort.reduce([1, 2, 3, 4], fn(a, b) { return a + b }) // 10
std.sort.reduce([1, 2, 3], fn(a, b) { return a + b }, 100) // 106
// longest-string idiom
var words = ["a", "bbb", "cc"]
var longest = std.sort.reduce(words, fn(best, w) {
return (len(w) > len(best)) ? w : best
})
print(longest) // bbb
Querying
every is true only if all elements pass; some if at least one passes. The
find family locates matches:
var nums = [1, 2, 3, 4]
std.sort.every(nums, fn(x) { return x > 0 }) // true
std.sort.some(nums, fn(x) { return x % 2 == 0 }) // true
std.sort.find(nums, fn(x) { return x > 2 }) // 3 (the VALUE)
std.sort.find_index(nums, fn(x) { return x > 2 }) // 2 (the INDEX)
std.sort.find_all([1, 2, 2, 3, 2], 2) // [1, 2, 4]
find returns the first matching value (null if none) and is a compact "first
object where ..." lookup:
var orders = [{id: 1, paid: false}, {id: 2, paid: true}]
var paid = std.sort.find(orders, fn(o) { return o.paid })
print(paid.id) // 2
See also
- std.seq —
range,chunk,take/drop,enumerate, set operations