containerModule:
module container
// Lookup
def safeGet : word -> data -> data // since PR#379
def descend : array(word) -> data -> data // since PR#379
// Update
def pathUpdate : array(word) -> data -> data -> data. // since PR#769
def pathUpdateAndAugment : array(word) -> data -> data -> data // since PR1804
// Iterating
def deepIterPath : (data -> array(word) -> null) -> data -> null // since PR#478
// Mapping
def shallowMap : (data -> data) -> data -> data
def deepMap : (data -> data) -> data -> data // since PR#379
// Searching
def shallowFind : (data -> bool) -> data -> data // since PR#379
def deepFind : (data -> bool) -> data -> data // since PR#379
def shallowFindMapped : (data -> S) -> data -> S // since PR#379
def deepFindMapped : (data -> S) -> data -> S // since PR#379
def shallowFindIndex : (data -> bool) -> data -> word // since PR#379
def deepFindPath : (data -> bool) -> data -> array(word) // since PR#379
// Merging
def shallowMerge : data -> data -> data // since PR#769
def deepMerge : data -> data -> data // since PR#769
def deepMergeBuilder : data -> data -> data // since PR#1700
def mergeReplaceBuilder: data -> data -> data // since PR#1675
// Conversion
def toStream : data -> data*
def toStreamPairs : data -> [data,data]*
module end
The container module contains functions that operate on both arrays and maps.
def safeGet : word -> data -> data // since PR#379
def descend : array(word) -> data -> data // since PR#379
safeGet(key,c) looks up a string-valued key in a map c or a number-valued key in an array c. If there is any problem doing the lookup, the value undefined will be returned (i.e. when c is neither a map nor an array, or when key or c are undefined, or when key does not fit to c, or when the container does not contain the key).
descend(path,c) walks the path in c and returns the final element. The path is an array of numbers and strings. For a number, it is expected that the remaining container is an array, and for a string it is expected that the remaining container is a map. On any problem walking the path, the value undefined is returned.
Example:
def c = { a: [1, 2, { b: "a", d: "X" } ], { b: { c: [ 3, "4" ] } } }
def v1 = descend(["a", 2, "d"], c) // returns "X"
def v2 = descend(["b"], c) // returns { c: [ 3, "4" ] }
def v3 = descend([], c) // returns c
def v4 = descend(["a", 3, "b"], c) // returns undefined
def v5 = descend(["b"], null) // returns undefined
def pathUpdate : array(word) -> data -> data -> data. // since PR#769
def pathUpdateAndAugment : array(word) -> data -> data -> data // since PR1804
The function pathUpdate(path, newValue, c) descends into the container c following path and changes the value there to newValue.
Example:
def c = { a: [1, 2, { b: "a", d: "X" } ], b: { c: [ 3, "4" ] } }
def d = pathUpdate(["a", 1], "hello", c)
// returns { a: [1, "hello", { b: "a", d: "X" } ], b: { c: [ 3, "4" ] } }
Note that there is also the built-in with notation for the case that the path is statically known:
def c = { a: [1, 2, { b: "a", d: "X" } ], b: { c: [ 3, "4" ] } }
def d = c with .a[1] = "hello"
// returns { a: [1, "hello", { b: "a", d: "X" } ], b: { c: [ 3, "4" ] } }
The function pathUpdateAndAugment(path, newValue, c) is similar to pathUpdate. The difference is that if the path runs into a part of c where the object fields and array indices are missing, these fields/indices are added.
Example:
pathUpdateAndAugment([ "p", "y", "z" ], "hello", { p: { x: "hi" }, q: [ 99 ] })
// returns { p: { x: "hi", y: { z: "hello" } }, q: [ 99 ] }