github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/docs/parser/lambda.md (about) 1 # `[{ Lambda }]` 2 3 > Iterate through structured data 4 5 ## Description 6 7 Lambdas, in Murex, are a concise way of performing various actions against 8 structured data. They're a convenience tool to range over arrays and objects, 9 similar to `foreach` and `formap`. 10 11 ### Etiquette 12 13 The intention of lambdas isn't to be used liberally within shell scripts but 14 rather than allow for more efficient one liners when performing quick, often 15 one-off, tasks in the interactive terminal. The terse syntax for lambdas 16 combined with it's adaptive functionality allow for flexibility when using, 17 albeit at the potential cost of readability. 18 19 For shell scripts where error handling, readability, and maintainability are a 20 concern, more conventional iteration blocks like `foreach` and `formap` are 21 recommended. 22 23 The reason lambda variables (known as **meta values** are single characters 24 also falls in line with this vision: they're terse to make one-liners 25 convenient and to discourage shell script usage. 26 27 ### Technical 28 29 Code running inside a lambda inherit a special variable, named **meta values**, 30 which hold the state for each iteration (see section below). 31 32 Lambdas will adapt its return value depending on the nature of the code it's 33 executing. 34 35 #### Filter 36 37 If your code returns a boolean data type, eg `[{$.v =~ "foobar"}]`, then the 38 lambda will filter that list or map, only returning values that match `true`, 39 discarding the others. 40 41 #### Update 42 43 If the **meta value** `v` (value) is updated then the lambda output reflects 44 that change. 45 46 The **meta value** `k` (key) works similarly for maps / objects too. However 47 updating it in arrays and lists currently does nothing. 48 49 This cannot be used in combination with **output**. 50 51 #### Output 52 53 If STDOUT isn't empty, then STDOUT is outputted rather than the object being 54 filtered and/or updated. 55 56 This usage most closely resembles `foreach` and `formap` except that the data 57 type of STDOUT is not preserved. 58 59 60 61 ## Examples 62 63 #### Filter 64 65 Filtering a map: 66 67 ``` 68 » %{hello: world, foo: bar} -> [{$.v == "world"}] 69 { 70 "hello": "world" 71 } 72 ``` 73 74 Filtering an array: 75 76 In this example we return the days of the week excluding todays day (in this 77 example, today is Friday) 78 79 ``` 80 » %[Monday..Sunday] -> [{$.v != datetime(--in {now} --out {py}%A)}] 81 [ 82 "Monday", 83 "Tuesday", 84 "Wednesday", 85 "Thursday", 86 "Saturday", 87 "Sunday" 88 ] 89 ``` 90 91 #### Update 92 93 Updating a map: 94 95 ``` 96 » %{hello: world, foo: bar} -> [{$.v == "world" -> if {$.v = "Earth"}}] 97 { 98 "foo": "bar", 99 "hello": "Earth" 100 } 101 ``` 102 103 Updating an array: 104 105 ``` 106 » %[monday..friday] -> [{$.v | tr [:lower:] [:upper:] | set $.v}] 107 [ 108 "MONDAY", 109 "TUESDAY", 110 "WEDNESDAY", 111 "THURSDAY", 112 "FRIDAY" 113 ] 114 ``` 115 116 #### Output 117 118 Output from a map: 119 120 ``` 121 » %{hello: world, foo: bar} -> [{$.v == "world" && out "Key '$.k' contains '$.v'"}] 122 Key 'hello' contains 'world' 123 ``` 124 125 Output from an array: 126 127 ``` 128 » %[Monday..Sunday] -> [{ $.v =~ "^S" && out "$.v is the weekend"}] 129 Saturday is the weekend 130 Sunday is the weekend 131 ``` 132 133 #### Foreach 134 135 Here we are using a lambda just as a terser way of writing a standard `foreach` 136 loop: 137 138 ``` 139 » %[Monday..Sunday] -> [{$.v =~ "^S" && $count+=1}]; echo "$count days being with an 'S'" 140 Error in `expr` (0,22): [json marshaller] no data returned 141 2 days being with an 'S' 142 ``` 143 144 However this is a contrived example. The more idiomatic way to write the above 145 would be (and notice it doesn't produce any empty array error too): 146 147 ``` 148 » %[Monday..Sunday] -> foreach day { $day =~ "^S" && $count+=1}; echo "$count days being with an 'S'" 149 2 days being with an 'S' 150 ``` 151 152 ...or even just using `regexp`, since the check is just a simple regexp match: 153 154 ``` 155 » %[Monday..Sunday] -> regexp m/^S/ -> count 156 2 157 ``` 158 159 ## Detail 160 161 ### Meta values 162 163 Meta values are a JSON object stored as the variable `$.`. The meta variable 164 will get overwritten by any other block which invokes meta values. So if you 165 wish to persist meta values across blocks you will need to reassign `$.`, eg 166 167 ``` 168 %[1..3] -> foreach { 169 meta_parent = $. 170 %[7..9] -> foreach { 171 out "$(meta_parent.i): $.i" 172 } 173 } 174 ``` 175 176 The following meta values are defined: 177 178 * `i`: iteration number (counts from one) 179 * `k`: key name (for arrays / lists this will count from zero) 180 * `v`: item value of map / object or array / list 181 182 ## See Also 183 184 * [`%[]` Create Array](../parser/create-array.md): 185 Quickly generate arrays 186 * [`%{}` Create Map](../parser/create-object.md): 187 Quickly generate objects and maps 188 * [`alter`](../commands/alter.md): 189 Change a value within a structured data-type and pass that change along the pipeline without altering the original source input 190 * [`datetime`](../commands/datetime.md): 191 A date and/or time conversion tool (like `printf` but for date and time values) 192 * [`foreach`](../commands/foreach.md): 193 Iterate through an array 194 * [`formap`](../commands/formap.md): 195 Iterate through a map or other collection of data 196 * [`regexp`](../commands/regexp.md): 197 Regexp tools for arrays / lists of strings 198 * [`while`](../commands/while.md): 199 Loop until condition false 200 201 <hr/> 202 203 This document was generated from [gen/parser/lambda_doc.yaml](https://github.com/lmorg/murex/blob/master/gen/parser/lambda_doc.yaml).