UNPKG

nodejs-polars

Version:

Polars: Blazingly fast DataFrames in Rust, Python, Node.js, R and SQL

694 lines (690 loc) 24.9 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.col = col; exports.cols = cols; exports.nth = nth; exports.lit = lit; exports.intRange = intRange; exports.intRanges = intRanges; exports.all = all; exports.argSortBy = argSortBy; exports.avg = avg; exports.concatList = concatList; exports.concatString = concatString; exports.count = count; exports.cov = cov; exports.exclude = exclude; exports.first = first; exports.format = format; exports.groups = groups; exports.head = head; exports.len = len; exports.last = last; exports.mean = mean; exports.median = median; exports.nUnique = nUnique; exports.pearsonCorr = pearsonCorr; exports.quantile = quantile; exports.select = select; exports.spearmanRankCorr = spearmanRankCorr; exports.tail = tail; exports.list = list; exports.struct = struct; exports.element = element; exports.allHorizontal = allHorizontal; exports.anyHorizontal = anyHorizontal; exports.maxHorizontal = maxHorizontal; exports.minHorizontal = minHorizontal; exports.sumHorizontal = sumHorizontal; const dataframe_1 = require("../dataframe"); const datatypes_1 = require("../datatypes"); const polars_internal_1 = __importDefault(require("../internals/polars_internal")); const series_1 = require("../series"); const utils_1 = require("../utils"); const expr_1 = require("./expr"); /** * __A column in a DataFrame.__ * Can be used to select: * * a single column by name * * all columns by using a wildcard `"*"` * * column by regular expression if the regex starts with `^` and ends with `$` * @param col * @example * ``` * > df = pl.DataFrame({ * > "ham": [1, 2, 3], * > "hamburger": [11, 22, 33], * > "foo": [3, 2, 1]}) * > df.select(col("foo")) * shape: (3, 1) * ╭─────╮ * │ foo │ * │ --- │ * │ i64 │ * ╞═════╡ * │ 3 │ * ├╌╌╌╌╌┤ * │ 2 │ * ├╌╌╌╌╌┤ * │ 1 │ * ╰─────╯ * > df.select(col("*")) * shape: (3, 3) * ╭─────┬───────────┬─────╮ * │ ham ┆ hamburger ┆ foo │ * │ --- ┆ --- ┆ --- │ * │ i64 ┆ i64 ┆ i64 │ * ╞═════╪═══════════╪═════╡ * │ 1 ┆ 11 ┆ 3 │ * ├╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┤ * │ 2 ┆ 22 ┆ 2 │ * ├╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┤ * │ 3 ┆ 33 ┆ 1 │ * ╰─────┴───────────┴─────╯ * > df.select(col("^ham.*$")) * shape: (3, 2) * ╭─────┬───────────╮ * │ ham ┆ hamburger │ * │ --- ┆ --- │ * │ i64 ┆ i64 │ * ╞═════╪═══════════╡ * │ 1 ┆ 11 │ * ├╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤ * │ 2 ┆ 22 │ * ├╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤ * │ 3 ┆ 33 │ * ╰─────┴───────────╯ * > df.select(col("*").exclude("ham")) * shape: (3, 2) * ╭───────────┬─────╮ * │ hamburger ┆ foo │ * │ --- ┆ --- │ * │ i64 ┆ i64 │ * ╞═══════════╪═════╡ * │ 11 ┆ 3 │ * ├╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┤ * │ 22 ┆ 2 │ * ├╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┤ * │ 33 ┆ 1 │ * ╰───────────┴─────╯ * > df.select(col(["hamburger", "foo"]) * shape: (3, 2) * ╭───────────┬─────╮ * │ hamburger ┆ foo │ * │ --- ┆ --- │ * │ i64 ┆ i64 │ * ╞═══════════╪═════╡ * │ 11 ┆ 3 │ * ├╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┤ * │ 22 ┆ 2 │ * ├╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┤ * │ 33 ┆ 1 │ * ╰───────────┴─────╯ * > df.select(col(pl.Series(["hamburger", "foo"])) * shape: (3, 2) * ╭───────────┬─────╮ * │ hamburger ┆ foo │ * │ --- ┆ --- │ * │ i64 ┆ i64 │ * ╞═══════════╪═════╡ * │ 11 ┆ 3 │ * ├╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┤ * │ 22 ┆ 2 │ * ├╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┤ * │ 33 ┆ 1 │ * ╰───────────┴─────╯ * ``` */ function col(col) { if (series_1.Series.isSeries(col)) { col = col.toArray(); } if (Array.isArray(col)) { return (0, expr_1._Expr)(polars_internal_1.default.cols(col)); } if (typeof col === "object" && Object.values(col)[0] === "DataType") { return (0, expr_1._Expr)(polars_internal_1.default.dtypeCols([col])); } return (0, expr_1._Expr)(polars_internal_1.default.col(col)); } function cols(...cols) { return col(cols.flat()); } /** * Select nth column index in a DataFrame. * @param n - Column index to select, starting at 0. * @example * ``` * > df = pl.DataFrame({ * > "ham": [1, 2, 3], * > "hamburger": [11, 22, 33], * > "foo": [3, 2, 1]}) * > df.select(nth(2)) * shape: (3, 1) * ╭─────╮ * │ foo │ * │ --- │ * │ i64 │ * ╞═════╡ * │ 3 │ * ├╌╌╌╌╌┤ * │ 2 │ * ├╌╌╌╌╌┤ * │ 1 │ * ╰─────╯ * ``` */ function nth(n) { return (0, expr_1._Expr)(polars_internal_1.default.nth(n)); } function lit(value) { if (Array.isArray(value)) { value = (0, series_1.Series)(value); } if (series_1.Series.isSeries(value)) { return (0, expr_1._Expr)(polars_internal_1.default.lit(value.inner())); } return (0, expr_1._Expr)(polars_internal_1.default.lit(value)); } function intRange(opts, end, step = 1, dtype, eager) { // @deprecated since 0.15.0 if (typeof opts?.low === "number") { return intRange(opts.low, opts.high, opts.step, opts.dtype, opts.eager); } if (typeof opts?.start === "number") { return intRange(opts.start, opts.end, opts.step, opts.dtype, opts.eager); } // if expression like pl.len() passed if (end === undefined || end === null) { end = opts; opts = 0; } const start = (0, expr_1.exprToLitOrExpr)(opts, false); end = (0, expr_1.exprToLitOrExpr)(end, false); if (eager) { const df = (0, dataframe_1.DataFrame)({ a: [1] }); return df .select(intRange(start, end, step).alias("intRange")) .getColumn("intRange"); } return (0, expr_1._Expr)(polars_internal_1.default.intRange(start, end, step, dtype || datatypes_1.DataType.Int64)); } function intRanges(start, end, step = 1, dtype = datatypes_1.DataType.Int64, eager) { start = (0, expr_1.exprToLitOrExpr)(start, false); end = (0, expr_1.exprToLitOrExpr)(end, false); step = (0, expr_1.exprToLitOrExpr)(step, false); if (eager) { const df = (0, dataframe_1.DataFrame)({ a: [1] }); return df .select(intRanges(start, end, step, dtype).alias("intRanges")) .getColumn("intRanges"); } return (0, expr_1._Expr)(polars_internal_1.default.intRanges(start, end, step, dtype)); } /** Alias for `pl.col("*")` */ function all() { return col("*"); } /** * Return the row indices that would sort the columns. * @param exprs Column(s) to arg sort by. Accepts expression input. * @param *more_exprs Additional columns to arg sort by, specified as positional arguments. * @param descending Sort in descending order. When sorting by multiple columns, can be specified per column by passing a sequence of booleans. * @example * ``` * const df = pl.DataFrame({"a": [0, 1, 1, 0], "b": [3, 2, 3, 2],}); * df.select(pl.argSortBy(pl.col("a"))); * shape: (4, 1) * ┌─────┐ * │ a │ * │ --- │ * │ u32 │ * ╞═════╡ * │ 0 │ * │ 3 │ * │ 1 │ * │ 2 │ * └─────┘ * ``` */ function argSortBy(exprs, descending = false) { if (!Array.isArray(descending)) { descending = Array.from({ length: exprs.length }, () => descending); } const by = (0, utils_1.selectionToExprList)(exprs); return (0, expr_1._Expr)(polars_internal_1.default.argSortBy(by, descending)); } function avg(column) { return mean(column); } function concatList(...exprs) { const items = (0, utils_1.selectionToExprList)(exprs, false); return expr_1.Expr(polars_internal_1.default.concatLst(items)); } function concatString(opts, sep = ",", ignoreNulls = true) { if (opts?.exprs) { return concatString(opts.exprs, opts.sep, opts.ignoreNulls); } const items = (0, utils_1.selectionToExprList)(opts, false); return expr_1.Expr(polars_internal_1.default.concatStr(items, sep, ignoreNulls)); } function count(column) { if (series_1.Series.isSeries(column)) { return column.len(); } return col(column).count(); } /** Compute the covariance between two columns/ expressions. */ function cov(a, b, ddof = 1) { a = (0, expr_1.exprToLitOrExpr)(a, false); b = (0, expr_1.exprToLitOrExpr)(b, false); return (0, expr_1._Expr)(polars_internal_1.default.cov(a, b, ddof)); } function exclude(...columns) { return col("*").exclude(columns); } function first(column) { if (!column) { return (0, expr_1._Expr)(polars_internal_1.default.first()); } if (series_1.Series.isSeries(column)) { if (column.length) { return column.get(0); } throw new RangeError("The series is empty, so no first value can be returned."); } return col(column).first(); } /** * String format utility for expressions * Note: strings will be interpolated as `col(<value>)`. if you want a literal string, use `lit(<value>)` * @example * ``` * > df = pl.DataFrame({ * ... "a": ["a", "b", "c"], * ... "b": [1, 2, 3], * ... }) * > df.select( * ... pl.format("foo_{}_bar_{}", pl.col("a"), "b").alias("fmt"), * ... ) * shape: (3, 1) * ┌─────────────┐ * │ fmt │ * │ --- │ * │ str │ * ╞═════════════╡ * │ foo_a_bar_1 │ * ├╌╌╌╌╌╌╌╌╌╌╌╌╌┤ * │ foo_b_bar_2 │ * ├╌╌╌╌╌╌╌╌╌╌╌╌╌┤ * │ foo_c_bar_3 │ * └─────────────┘ * * // You can use format as tag function as well * > pl.format("foo_{}_bar_{}", pl.col("a"), "b") // is the same as * > pl.format`foo_${pl.col("a")}_bar_${"b"}` * ``` */ function format(strings, ...expr) { if (typeof strings === "string") { const s = strings.split("{}"); if (s.length - 1 !== expr.length) { throw new RangeError("number of placeholders should equal the number of arguments"); } return format(s, ...expr); } const d = (0, utils_1.range)(0, Math.max(strings.length, expr.length)) .flatMap((i) => { const sVal = strings[i] ? lit(strings[i]) : []; const exprVal = expr[i] ? (0, expr_1.exprToLitOrExpr)(expr[i], false) : []; return [sVal, exprVal]; }) .flat(); return concatString(d, ""); } /** Syntactic sugar for `pl.col(column).aggGroups()` */ function groups(column) { return col(column).aggGroups(); } function head(column, n) { if (series_1.Series.isSeries(column)) { return column.head(n); } return (0, expr_1.exprToLitOrExpr)(column, false).head(n); } /** Return the number of elements in the column. This is similar to `COUNT(*)` in SQL. @return Expr - Expression of data type :class:`UInt32`. @example ``` >>> const df = pl.DataFrame( ... { ... "a": [1, 2, None], ... "b": [3, None, None], ... "c": ["foo", "bar", "foo"], ... } ... ) >>> df.select(pl.len()) shape: (1, 1) ┌─────┐ │ len │ │ --- │ │ u32 │ ╞═════╡ │ 3 │ └─────┘ ``` Generate an index column by using `len` in conjunction with :func:`intRange`. ``` >>> df.select( ... pl.intRange(pl.len(), dtype=pl.UInt32).alias("index"), ... pl.all(), ... ) shape: (3, 4) ┌───────┬──────┬──────┬─────┐ │ index ┆ a ┆ b ┆ c │ │ --- ┆ --- ┆ --- ┆ --- │ │ u32 ┆ i64 ┆ i64 ┆ str │ ╞═══════╪══════╪══════╪═════╡ │ 0 ┆ 1 ┆ 3 ┆ foo │ │ 1 ┆ 2 ┆ null ┆ bar │ │ 2 ┆ null ┆ null ┆ foo │ └───────┴──────┴──────┴─────┘ ``` */ function len() { return (0, expr_1._Expr)(polars_internal_1.default.len()); } /** Get the last value. */ function last(column) { if (series_1.Series.isSeries(column)) { if (column.length) { return column.get(-1); } throw new RangeError("The series is empty, so no last value can be returned."); } return (0, expr_1.exprToLitOrExpr)(column, false).last(); } function mean(column) { if (series_1.Series.isSeries(column)) { return column.mean(); } return (0, expr_1.exprToLitOrExpr)(column, false).mean(); } function median(column) { if (series_1.Series.isSeries(column)) { return column.median(); } return (0, expr_1.exprToLitOrExpr)(column, false).median(); } function nUnique(column) { if (series_1.Series.isSeries(column)) { return column.nUnique(); } return (0, expr_1.exprToLitOrExpr)(column, false).nUnique(); } /** Compute the pearson's correlation between two columns. */ function pearsonCorr(a, b) { a = (0, expr_1.exprToLitOrExpr)(a, false); b = (0, expr_1.exprToLitOrExpr)(b, false); return (0, expr_1._Expr)(polars_internal_1.default.pearsonCorr(a, b)); } function quantile(column, q) { if (series_1.Series.isSeries(column)) { return column.quantile(q); } return (0, expr_1.exprToLitOrExpr)(column, false).quantile(q); } /** * __Run polars expressions without a context.__ * * This is syntactic sugar for running `df.select` on an empty DataFrame. */ function select(expr, ...exprs) { return (0, dataframe_1.DataFrame)({}).select(expr, ...exprs); } /** Compute the spearman rank correlation between two columns. */ function spearmanRankCorr(a, b) { a = (0, expr_1.exprToLitOrExpr)(a, false); b = (0, expr_1.exprToLitOrExpr)(b, false); return (0, expr_1._Expr)(polars_internal_1.default.spearmanRankCorr(a, b, false)); } function tail(column, n) { if (series_1.Series.isSeries(column)) { return column.tail(n); } return (0, expr_1.exprToLitOrExpr)(column, false).tail(n); } /** Syntactic sugar for `pl.col(column).list()` */ function list(column) { return (0, expr_1.exprToLitOrExpr)(column, false).list(); } function struct(exprs) { exprs = Array.isArray(exprs) ? exprs : [exprs]; if (series_1.Series.isSeries(exprs[0])) { return select((0, expr_1._Expr)(polars_internal_1.default.asStruct(exprs.map((e) => polars_internal_1.default.lit(e.inner()))))).toSeries(); } exprs = (0, utils_1.selectionToExprList)(exprs); return (0, expr_1._Expr)(polars_internal_1.default.asStruct(exprs)); } /** * Alias for an element in evaluated in an `eval` expression. * @example * * A horizontal rank computation by taking the elements of a list * * >df = pl.DataFrame({"a": [1, 8, 3], "b": [4, 5, 2]}) * >df.withColumn( * ... pl.concatList(["a", "b"]).arr.eval(pl.element().rank()).alias("rank") * ... ) * shape: (3, 3) * ┌─────┬─────┬────────────┐ * │ a ┆ b ┆ rank │ * │ --- ┆ --- ┆ --- │ * │ i64 ┆ i64 ┆ list[f32] │ * ╞═════╪═════╪════════════╡ * │ 1 ┆ 4 ┆ [1.0, 2.0] │ * ├╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤ * │ 8 ┆ 5 ┆ [2.0, 1.0] │ * ├╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤ * │ 3 ┆ 2 ┆ [2.0, 1.0] │ * └─────┴─────┴────────────┘ * * A mathematical operation on array elements * * >df = pl.DataFrame({"a": [1, 8, 3], "b": [4, 5, 2]}) * >df.withColumn( * ... pl.concatList(["a", "b"]).arr.eval(pl.element().multiplyBy(2)).alias("a_b_doubled") * ... ) * shape: (3, 3) * ┌─────┬─────┬─────────────┐ * │ a ┆ b ┆ a_b_doubled │ * │ --- ┆ --- ┆ --- │ * │ i64 ┆ i64 ┆ list[i64] │ * ╞═════╪═════╪═════════════╡ * │ 1 ┆ 4 ┆ [2, 8] │ * ├╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┤ * │ 8 ┆ 5 ┆ [16, 10] │ * ├╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┤ * │ 3 ┆ 2 ┆ [6, 4] │ * └─────┴─────┴─────────────┘ */ function element() { return col(""); } /** * Compute the bitwise AND horizontally across columns. * @param *exprs * Column(s) to use in the aggregation. Accepts expression input. Strings are * parsed as column names, other non-expression inputs are parsed as literals. * * @example * ``` * >>> const df = pl.DataFrame( * { * "a": [false, false, true, true], * "b": [false, true, null, true], * "c": ["w", "x", "y", "z"], * } * ) * >>> df.withColumns(pl.allHorizontal([pl.col("a"), pl.col("b")])) * shape: (4, 4) * ┌───────┬───────┬─────┬───────┐ * │ a ┆ b ┆ c ┆ all │ * │ --- ┆ --- ┆ --- ┆ --- │ * │ bool ┆ bool ┆ str ┆ bool │ * ╞═══════╪═══════╪═════╪═══════╡ * │ false ┆ false ┆ w ┆ false │ * │ false ┆ true ┆ x ┆ false │ * │ true ┆ null ┆ y ┆ null │ * │ true ┆ true ┆ z ┆ true │ * └───────┴───────┴─────┴───────┘ * ``` */ function allHorizontal(exprs) { exprs = Array.isArray(exprs) ? exprs : [exprs]; exprs = (0, utils_1.selectionToExprList)(exprs); return (0, expr_1._Expr)(polars_internal_1.default.allHorizontal(exprs)); } /** * Compute the bitwise OR horizontally across columns. * @param *exprs * Column(s) to use in the aggregation. Accepts expression input. Strings are * parsed as column names, other non-expression inputs are parsed as literals. * @example * ``` * >>> const df = pl.DataFrame( * ... { * ... "a": [false, false, true, null], * ... "b": [false, true, null, null], * ... "c": ["w", "x", "y", "z"], * ... } * ... ) * >>> df.withColumns(pl.anyHorizontal([pl.col("a"), pl.col("b")])) * shape: (4, 4) * ┌───────┬───────┬─────┬───────┐ * │ a ┆ b ┆ c ┆ any │ * │ --- ┆ --- ┆ --- ┆ --- │ * │ bool ┆ bool ┆ str ┆ bool │ * ╞═══════╪═══════╪═════╪═══════╡ * │ false ┆ false ┆ w ┆ false │ * │ false ┆ true ┆ x ┆ true │ * │ true ┆ null ┆ y ┆ true │ * │ null ┆ null ┆ z ┆ null │ * └───────┴───────┴─────┴───────┘ * ``` */ function anyHorizontal(exprs) { exprs = Array.isArray(exprs) ? exprs : [exprs]; exprs = (0, utils_1.selectionToExprList)(exprs); return (0, expr_1._Expr)(polars_internal_1.default.anyHorizontal(exprs)); } /** * Get the maximum value horizontally across columns. * @param *exprs * Column(s) to use in the aggregation. Accepts expression input. Strings are * parsed as column names, other non-expression inputs are parsed as literals. * @example * ``` * >>> const df = pl.DataFrame( * ... { * ... "a": [1, 8, 3], * ... "b": [4, 5, null], * ... "c": ["x", "y", "z"], * ... } * ... ) * >>> df.withColumns(pl.maxHorizontal(pl.col("a"), pl.col("b"))) * shape: (3, 4) * ┌─────┬──────┬─────┬─────┐ * │ a ┆ b ┆ c ┆ max │ * │ --- ┆ --- ┆ --- ┆ --- │ * │ i64 ┆ i64 ┆ str ┆ i64 │ * ╞═════╪══════╪═════╪═════╡ * │ 1 ┆ 4 ┆ x ┆ 4 │ * │ 8 ┆ 5 ┆ y ┆ 8 │ * │ 3 ┆ null ┆ z ┆ 3 │ * └─────┴──────┴─────┴─────┘ * ``` */ function maxHorizontal(exprs) { exprs = Array.isArray(exprs) ? exprs : [exprs]; exprs = (0, utils_1.selectionToExprList)(exprs); return (0, expr_1._Expr)(polars_internal_1.default.maxHorizontal(exprs)); } /** * Get the minimum value horizontally across columns. * @param *exprs * Column(s) to use in the aggregation. Accepts expression input. Strings are * parsed as column names, other non-expression inputs are parsed as literals. * @example * ``` * >>> const df = pl.DataFrame( * ... { * ... "a": [1, 8, 3], * ... "b": [4, 5, null], * ... "c": ["x", "y", "z"], * ... } * ... ) * >>> df.withColumns(pl.minHorizontal(pl.col("a"), pl.col("b"))) * shape: (3, 4) * ┌─────┬──────┬─────┬─────┐ * │ a ┆ b ┆ c ┆ min │ * │ --- ┆ --- ┆ --- ┆ --- │ * │ i64 ┆ i64 ┆ str ┆ i64 │ * ╞═════╪══════╪═════╪═════╡ * │ 1 ┆ 4 ┆ x ┆ 1 │ * │ 8 ┆ 5 ┆ y ┆ 5 │ * │ 3 ┆ null ┆ z ┆ 3 │ * └─────┴──────┴─────┴─────┘ * ``` */ function minHorizontal(exprs) { exprs = Array.isArray(exprs) ? exprs : [exprs]; exprs = (0, utils_1.selectionToExprList)(exprs); return (0, expr_1._Expr)(polars_internal_1.default.minHorizontal(exprs)); } /** * Sum all values horizontally across columns. * @param *exprs * Column(s) to use in the aggregation. Accepts expression input. Strings are * parsed as column names, other non-expression inputs are parsed as literals. * @example * ``` * >>> const df = pl.DataFrame( * ... { * ... "a": [1, 8, 3], * ... "b": [4, 5, null], * ... "c": ["x", "y", "z"], * ... } * ... ) * >>> df.withColumns(pl.sumHorizontal(pl.col("a"), ol.col("b"))) * shape: (3, 4) * ┌─────┬──────┬─────┬──────┐ * │ a ┆ b ┆ c ┆ sum │ * │ --- ┆ --- ┆ --- ┆ --- │ * │ i64 ┆ i64 ┆ str ┆ i64 │ * ╞═════╪══════╪═════╪══════╡ * │ 1 ┆ 4 ┆ x ┆ 5 │ * │ 8 ┆ 5 ┆ y ┆ 13 │ * │ 3 ┆ null ┆ z ┆ null │ * └─────┴──────┴─────┴──────┘ * ``` */ function sumHorizontal(exprs) { exprs = Array.isArray(exprs) ? exprs : [exprs]; exprs = (0, utils_1.selectionToExprList)(exprs); return (0, expr_1._Expr)(polars_internal_1.default.sumHorizontal(exprs, true)); } // // export function collect_all() {} // // export function all() {} // fold // // export function any() {} // fold // // export function apply() {} // lambda // // export function fold() {} // // export function map_binary() {} //lambda // // export function map() {} //lambda // // export function max() {} // fold // // export function min() {} // fold // // export function sum() {} // fold