Implementing some utilities.

A great way to pick up some tricks is to look at implementations of common utility functions in a range of languages. It’s especially interesting to see them when they’re implemented in lower level languages (C, C++, D, Zig) as they often display more mechanical sympathy than higher level languages tend to.

That said, higher level and/or dynamically typed languages have some niceties that are worth learning if nothing but to know that they’re out there.

Here are some of the more common examples that tend to come up in a lot of languages, especially those with a functional nature about them.




Note: Whilst a lot of these borrow names from functional languages, most implementations shown here rely on mutation. The language of choice is JavaScript, as it's expressive and popular enough for the purpose of demonstration.



Map.

const map = (array, f) => {
    for (let i = 0; i < array.length; i++) {
            array[i] = f(array[i])
    }
    return array
}

Good ole' map! Takes a array and a function, returns the array with all elements ran through (and replaced with the return from) the provided function.

This implementation utilizes the fact that JS arrays can hold arbitrarly values, saving the need for creating a new array of the correct output type.

Example.

const increment = n => n + 1

$ map([1, 2, 3], increment)
> Array(3) [ 2, 3, 4 ]

Filter.

const filter = (array, f) => {
    let n = 0
    for (let i = 0; i < array.length; i++) {
        if (f(array[i])) {
                array[n] = array[i]
                n++
        }
    }
    return array.slice(0, n)
}

Removes all elements that don’t match the provided predicate function.

Mutates the array in place, slicing off the end. No new array needed.

If you’re worried about mutating previous references, creating a new array with the same length works equally well, with one added allocation.

Example.

const positiveNumber = n => n > 0

$ filter([-1, 0, 1, 2, 3], positiveNumber)
> Array (2) [ 1, 2, 3 ]

Replace.

const replace = (array, predicate, f) =>
    map(array, x => predicate(x) ? f(x) : x)

Replaces an item in an array matched by predicate.

Example.

const isZero = n => n == 0

$ replace([0, 2, 3], isZero, increment)
> Array (3) [ 1, 2, 3 ]

First.

const first = (array, predicate) =>
    filter(array, predicate)[0]

Filters an array and returns its first element.

Works great if implemented as an expression, throws on null otherwise.

Example.

$ first([1, 2, 3], isOne)
> 0

$ first([1, 2, 3], isFour)
> undefined

Or.

const or = (item, or) => item ? item : or

For situations where null/nil/undefined is undesirable.

Example.

const personOrDefault = (users, name, defaultPerson) => 
    or(first(users, p => p.name == name), 
       defaultPerson)

const people = [
    { name: 'Berta' },
    { name: 'NotSteve' }
]

const defaultPerson = { name: 'Default' }

$ personOrDefault(people, 'Berta', defaultPerson)
> Object { name: 'Berta' }

$ personOrDefault(people, 'Steve', defaultPerson)
> Object { name: 'Default' }

SetProperty.

const setProperty = (object, property, value) => {
    return { ...object, [property]: value }
}

Returns an object with one property modified.

Necessary for things like mapping an array of objects.

Example.

const yourNameIsSteve = obj =>
    setProperty(obj, 'name', 'Steve')

const everyoneIsNamedSteve = people =>
    map(people, yourNameIsSteve)

$ yourNameIsSteve(first(people))
> Object { name: 'Steve' }

$ everyoneIsNamedSteve(people)
> Array (2) [ Object { name: 'Steve' }, Object { name: 'Steve' }]

All.

const all = (array, predicate) =>
    filter(array, predicate).length == array.length

Returns true if predicate matches the entire array.

Example.

$ all([1, 2, 3], n => n == 2)
> false

$ all([1, 2, 3], n => n > 0)
> true

Any.

const any = (array, predicate) =>
    find(array, predicate) != null

Returns true if predicate matches one item in array.

Example.

$ any([1, 2, 3], n => n == 0)
> false

$ any([1, 2, 3], n = > n == 2)
> true

Append.

const append = (array, item) =>
    array ? [...array, item] : [item]

Returns the array with item appended.

Example.

$ append([1, 2, 3], 4)
> Array (4) [ 1, 2, 3, 4 ]

Identity.

const identity = a => a

Shorthand for evaluating booleans. Works great in conjunction with truthiness.

Example.

$ [true, false].filter(identity)
> Array (1) [ true ]

Example with function chaining.

const hasErrors = items => 
    items.map(i => Object.values(i.errors))
         .filter(identity)
         .length > 0

const items = [ { price: 50,
                  errors: { priceIsNull: false } },
                { price: null,
                  errors: { priceIsNull: true } } ]

$ hasErrors(items)
> true