How do I loop through a list using listReplace?
Quite often, there is a task where you have a list
and you need to sequentially process each of its elements to get a new list
with processed elements.
For this, we use the function listReplace.
=: listReplace(list: $startlist; action: $action; value: "value")
startlist: selectList(table: 'table'; field: 'num'; where: 'status' = 4)
action: select(table: 'table_2'; field: 'price'; where: 'num' = $#value)
listReplace takes the starting list
and performs action
for each of its elements.
We can set a variable in value
that will store the value of the list
element being processed at the current moment.
Thus, action
will be called as many times as there were elements in the list.
As a result, we will get a new list with the same number of elements, but with different values — the values that we calculated in action
.
Will the code in the action be executed for each row?
Yes. For each element of the list.
How do I know the number of the row to be processed in the code called in the action?
In listReplace, there is a parameter key
where you can specify the name of the variable that will be assigned the number of the processed row.
If we want to return ""
for the first 5 rows:
=: listReplace(list: $startlist; action: $action; value: "value"; key: "key")
startlist: selectList(table: 'table'; field: 'num'; where: 'status' = 4)
action: if(condition: $#key <= 4; then: ""; else: $sel)
// remember that list numbering starts from 0
sel: select(table: 'table_2'; field: 'price'; where: 'num' = $#value)
How can I use the value of the processed row in the code called in the action?
In your value
parameter, you should specify the name of the variable to which the value will be passed. And this variable can be accessed as $#value_name_param
.
What should we pay attention to if we have more than one listReplace in the same code?
Make sure that your variable names do not overlap.
Can we add an item with a key if we are processing a list?
No, action
with a key like action: "key" = $value
is available for rowlist
.
How do we add or replace an item with a key if we are processing rowList?
=: listReplace(list: $startlist; action: "price" = $action; value: "value")
startlist: selectRowList(table: 'table'; field: 'num'; field: 'price'; where: 'status' = 4)
action: $#value[price] * $kf
kf: select(table: 'table_2'; field: 'kf'; where: 'num' = $#value[num])
Here we take a rowlist
and adjust the values in the price
column. Note that the value of the startlist
row is passed to value
, and for rowlist
, the value of the row is row
— therefore, the reference in $#value
should be supplemented with the appropriate key (column) — $#value[price]
.
If we specify an existing key in the rowlist
in action
, it will be overwritten. If we specify a key that is not in the initial rowlist
, an additional column with that key will be added.
How to create a base for the loop with listNumberRange?
Sometimes we need to create a base list to iterate over. For this, listNumberRange is suitable.
For example, let's create a list of days from 1 to 31:
=: listNumberRange(min: 1; max: 31; step: 1)
If a rowlist
is needed for further processing instead of a list
:
=: rowListCreate(field: "range" = $range)
range: listNumberRange(min: 1; max: 31; step: 1)
How to make it easier if you need to do the same kind of mathematical action on all the items in a list?
If you need to perform the same mathematical operation on all elements of a list, there is a simpler function listMath.
=: listMath(list: $list; operator: "*"; num: 3)
list: listCreate(item: 1; item: 2; item: 11; item: 21)
// Result: [ 3, 6, 33, 63]