Map and Filter Erlang functions
  • 28 Oct 2022
  • 3 Minutes to read
  • 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',
  '==',
  '/=',
  '=<',
  '<',
  '>=',
  '>',
  '=:=',
  '=/=',
  '++',
  '--'
]).