web/book/src/reference/stdlib/tuple.md
The standard library defines the following functions for manipulating tuples:
tuple_reduceApplies a two-parameter function cumulatively across a tuple, in order to reduce the tuple to a single value.
from invoices
derive {
cleared = tuple_reduce std.and {
received, processed, packed, shipped
}
}
When the initial: named parameter is provided, its value will be used to
initialize the reduction operation, and will be the default value if the tuple
is empty.
from test
derive {
mysum = tuple_reduce initial:0 add {1, 2, 3}
}
If initial is not provided, when the tuple has exactly one entry, its value
will be returned; when the tuple is empty, an error will be raised.
tuple_mapApplies a function to each entry in a tuple, returning a tuple. Aliases defined in the tuple will be passed through to the output.
prql target:sql.duckdb
from invoices
select (
tuple_map (date.to_text "%d/%m/%Y") {
rcv_txt = received_on,
prc_txt = processed_on,
}
)
tuple_zipCombines two tuples into one tuple by aligning them in parallel and creating
tuples out of each aligned pair. This can be used in conjunction with
tuple_map and tuple_reduce in various ways:
from invoices
derive (
tuple_zip {x, y} {u, v}
tuple_map (tuple_reduce (func a b -> a + b))
)
tuple_uniqIteratively deduplicates a tuple by alias (or, when an alias is not defined, by its referenced column name). This can help to have more control over situations when a column may be being overwritten.
For example, the following includes all columns from both invoices and
shipments in the final result, even those that have overlapping names:
let shipments = (from shipments | select {id, invoice_id, date_of, shipped_on})
from invoices
select {id, date_of, processed}
join shipments (this.id == that.invoice_id)
Adding select (tuple_uniq take:late {invoices.*, shipments.*}) will allow the
columns from shipments to appear in the output taking precedence over those
from invoices.
let shipments = (from shipments | select {id, invoice_id, date_of, shipped_on})
from invoices
select {id, date_of, processed}
join shipments (this.id == that.invoice_id)
select (tuple_uniq take:late {invoices.*, shipments.*})
Using take:early rather than take:late flips the priority.
let shipments = (from shipments | select {id, invoice_id, date_of, shipped_on})
from invoices
select {id, date_of, processed}
join shipments (this.id == that.invoice_id)
select (tuple_uniq take:early {invoices.*, shipments.*})
Items in a tuple without a name or an alias will be dropped.
from test
select (tuple_uniq {x, 5, y})
tuple_reverseReverses the order of a tuple.
from test
select (tuple_reverse {x, y, z})