Map and Filter Erlang functions
• 28 Oct 2022
• Contributors
• Dark
Light
• PDF

# Map and Filter Erlang functions

• Dark
Light
• PDF

For Set Parameters nodes, a native support of `\$.map()` and `\$.filter()` Erlang functions is available similar to the `\$.math()`, `\$.unixtime()` support. The support for `\$.map()` and `\$.filter()` is aimed at making responses from external APIs more lightweight and making tasks smaller after going through API Call nodes.

#### Functions Syntax

`map()` and `filter()` functions are used in the following construction:

`\$.map(fun(Item) -> end, arr)`
`\$.filter(fun(Item) -> end, value)`,
where
fun-supported function (see the list below);
Item-arbitrary value;

Item syntax

"Item" value must start from a capital letter

arr-parameter of an input task, which contains an array;
value-a single value.

A function body is written after the `->`, in which you can write allowed expressions using simple operations from ALLOWED_INF_EXPRS (sum, add, subtract, etc.), as well as some functions from ALLOWED_EXT_FUNS.

### \$.map Use Examples

Multiplying all array elements by a specified value
On a Set Parameters node input, let's take a task containing the `“a”` array:

``````"a": [1,2,3]
``````

Let's write the following \$.map function in a Set Parameters node:

``````"b": "\$.map(fun(Item) -> Item*2 end, {{a}})"
``````

With this function used, each `“а”` array element is multiplied by 2, and the results are written to `“b”` array. This results in the following `“b”` array:

``````"b": "[2,4,6]"
``````

Converting array objects
Suppose we have the following task containing the `“d”` array on a Set Parameters node input:

`````` "d": [
{
"conv_id": 1,
"ref": "a",
"uuid": "erjnkjn"
},
{
"conv_id": 2,
"ref": "b",
"uuid": "lklll"
},
{
"conv_id": 3,
"ref": "c",
"uuid": "fdxfdcf"
}
]
``````

Let's write the following `\$.map` function to a Set Parameters node:

``````"d1": "\$.map(fun([{<<\"conv_id\">>, ConvId}, {<<\"ref\">>, Ref}, Item]) -> [{<<\"conv_id\">>, ConvId}, {<<\"ref\">>, Ref}] end, {{d}})"
``````

After we've written the function results to the `“d1”` array, we get the following:

``````"d1": [
{
"conv_id": 1,
"ref": "a"
},
{
"conv_id": 2,
"ref": "b"
},
{
"conv_id": 3,
"ref": "c"
}
]
}
``````

Reading values from proplists in an array
Suppose we have the following `“a1”` array:

``````"a1": [{"test":1}, {"test":2}, {"test":3}]
``````

When using the \$.map and \$.filter functions, the following entities will be processed in the Item one by one:

``````[{<<"test">>, 1}]
[{<<"test">>, 2}]
[{<<"test">>, 3}]
``````

Let's write the following `\$.map` function to a Set Parameters node:

``````"b1": "\$.map(fun(Item) -> Test = proplists:get_value(<<\"test\">>, Item), [{<<\"test2\">>, Test*5} | Item] end, {{a1}})"
``````

This function reads values from the `"test"` proplist.The following list of values will be inside the `Item`:

``````   "b1": [
{
"test2": 5,
"test": 1
},
{
"test2": 10,
"test": 2
},
{
"test2": 15,
"test": 3
}
]
``````

### \$.filter Use Examples

Filtering off uneven numbers from an array and writing even numbers to another array
Suppose we have the following `"b"` task:

``````[1,2,3,4,5,6,7,8,9,10,11,12,13,14]
``````

Let's write the following function to a Set Parameters node:

``````"b1": "\$.filter(fun(Item) when Item rem 2 < 1 -> true; (_) -> false end, {{b}})"
``````

We will get the response:

``````"b1":[2,4,6,8,10,12,14]
``````

Filtering off a specified value from a proplist and writing remaining values to an array

Suppose we have the following task:

``````"b":[{"test":1},{"test":2},{"test":3},{"test":4},{"test":5},{"test":6},{"test":7},{"test":8}]
``````

Let's write the following function to a Set Parameters node:

``````"b1": "\$.filter(fun(Item) -> Test = proplists:get_value(<<\"test\">>, Item) =/= 5 end, {{b}})"
``````

We will get the response:

``````"b1":[{"test":1},{"test":2},{"test":3},{"test":4},{"test":6},{"test":7},{"test":8}]
``````

Filtering off float or integer values from a proplist and writing remaining values to an array

Suppose we have the following task:

``````"b": [{"test": "3FF"},{"test": 30},{"test": [{"a": 1}]},{"test": 30.3},{"test": true}]
``````

Let's write, for example, this function for filtering integer values:

``````"is_integer": "\$.filter(fun(Item) -> Test = proplists:get_value(<<\"test\">>, Item), is_integer(Test) end, {{b}})"
``````

or this function to a Set Parameters node for filtering float values:

``````"is_float": "\$.filter(fun(Item) -> Test = proplists:get_value(<<\"test\">>, Item), is_float(Test) end, {{b}})"
``````

We will get the response:

`````` "is_float": [
{
"test": 30.3
}
]
"is_integer": [
{
"test": 30
}
]
``````

### List of supported functions

``````-define(ALLOWED_EXT_FUNS, [
{proplists,'_','_'},
{base64,'_','_'},

{binary, split, '_'},
{binary, replace, '_'},

{eutils, get_value, 2},
{eutils, from_json, '_'},
{eutils, to_json, 1},

{erlang,binary_to_float,1},
{erlang,binary_to_integer,1},

{erlang,integer_to_binary,1},
{erlang,integer_to_binary,2},

{erlang,round,1},

{erlang, is_integer, 1},
{erlang, is_binary, 1},
{erlang, is_list, 1},
{erlang, is_float, 1},
{erlang, is_boolean, 1},
{erlang, is_number, 1},

{erlang, hd, 1},
{erlang, tl, 1}

]).
``````

The list items have the following structure:
`{module,function, number of arguments}`
For example, `{eutils, to_json, 1}` means that the `to_json` function from the `eutils` module is supported with the number of arguments of 1.
`'_'` means an unlimited number of either supported arguments or functions, or both.

``````-define(ALLOWED_INF_EXPRS, [
'+',
'-',
'*',
'/',
'bnot',
'div',
'rem',
'band',
'bor',
'bxor',
'bsl',
'bsr',
'not',
'and',
'or',
'xor',
'andalso',
'orelse',
'==',
'/=',
'=<',
'<',
'>=',
'>',
'=:=',
'=/=',
'++',
'--'
]).
``````