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]