Skip to main content

rl_lang/docs/entries/tutorial/t2/
p_a7.rs

1use crate::docs::entry::{ConceptCategory, ConceptEntry, DescriptionEntry, DescriptionKind};
2
3pub static ADV_CSV_MUTATION: ConceptEntry = ConceptEntry {
4    name: "7. mutating CSV data",
5    summary: "mutating CSV data",
6    category: ConceptCategory::Tooling,
7    prerequisites: &[],
8    descriptions: &[
9        DescriptionEntry {
10            kind: DescriptionKind::Explanation,
11            title: None,
12            description: "arrays in rl are values - when you filter or map you get a new array, the original is unchanged. mutation means building a new array with the change applied. this is the same pattern arr_push uses",
13            examples: &[
14                "get arr_map from std::array\n\n// update a field in one row, return a new rows array\nfn csv_update_field(arr[arr[string]] rows, string id, int col, string value) -> arr[arr[string]] {\n    return arr_map(rows, fn(arr[string] row) -> arr[string] {\n        if (row[COL_ID] != id) { return row }\n        // build updated row\n        dec arr[string] updated = row\n        updated[col] = value\n        return updated\n    })\n}",
15            ],
16            expected_output: &[],
17        },
18        DescriptionEntry {
19            kind: DescriptionKind::Explanation,
20            title: None,
21            description: "deleting a row means filtering it out. arr_filter with the opposite condition gives you every row except the one you want gone",
22            examples: &[
23                "get arr_filter from std::array\n\nfn csv_remove_by_id(arr[arr[string]] rows, string id) -> arr[arr[string]] {\n    return arr_filter(rows, fn(arr[string] row) -> bool {\n        return row[COL_ID] != id\n    })\n}",
24            ],
25            expected_output: &[],
26        },
27        DescriptionEntry {
28            kind: DescriptionKind::Explanation,
29            title: None,
30            description: "adding a row means generating a new ID first. the simplest approach: find the current max ID and add 1. arr_reduce works well here",
31            examples: &[
32                "get arr_reduce  from std::array\nget to_int, to_string from std::types\n\nfn csv_next_id(arr[arr[string]] rows) -> string {\n    if (len(rows) == 0) { return \"1\" }\n    dec int max_id = arr_reduce(\n        rows,\n        fn(int acc, arr[string] row) -> int {\n            dec int id = to_int(row[COL_ID])\n            if (id > acc) { return id }\n            return acc\n        },\n        0\n    )\n    return to_string(max_id + 1)\n}",
33            ],
34            expected_output: &[],
35        },
36        DescriptionEntry {
37            kind: DescriptionKind::Explanation,
38            title: None,
39            description: "exercise: add these mutation functions to csv.rl:\n  csv_add_row(rows, fields)           -> arr[arr[string]]\n  csv_remove_by_id(rows, id)          -> arr[arr[string]]\n  csv_update_field(rows, id, col, val)-> arr[arr[string]]\n  csv_next_id(rows)                   -> string",
40            examples: &[
41                "// test in main.rl\ndec arr[arr[string]] rows = []\n\n// add\nrows = csv_add_row(rows, [csv_next_id(rows), \"pending\", \"1750000000\", \"buy milk\"])\nrows = csv_add_row(rows, [csv_next_id(rows), \"pending\", \"1750000100\", \"write code\"])\nprintln(len(rows)) // 2\n\n// update\nrows = csv_update_field(rows, \"1\", COL_STATUS, \"done\")\nprintln(csv_find_by_id(rows, \"1\")[COL_STATUS]) // done\n\n// remove\nrows = csv_remove_by_id(rows, \"1\")\nprintln(len(rows)) // 1",
42            ],
43            expected_output: &[],
44        },
45    ],
46    pitfalls: &[],
47    related: &[],
48    related_stdlib: &[],
49    since: None,
50};