> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cognite.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Mapping concepts

> Learn about the hosted extractor mapping language for transforming JSON structures with functional expressions similar to JavaScript.

The hosted extractor mapping language translates JSON structures to other JSON structures. The language is similar to JavaScript and is purely *functional*. A mapping is a single expression that describes how to build one JSON structure from another.

## Variables

Use these input objects to define a mapping:

* `input` - This is the content of the received message, parsed into an object.

* `context` - This contains information about the message. The content of this object varies between the different hosted extractors.

  For MQTT, the `context` object contains

  * `topic`: which topic the message arrived at

For examples of using these variables, see [Handling more data in a single message](/cdf/integration/guides/extraction/hosted_extractors/hosted_extractors_custom_mappings#handling-more-data-in-a-single-message).

When variables are objects or arrays they can be selected from. For example, given the object

```json theme={"languages":{"custom":["/_languages/kuiper.json","../_languages/kuiper.json"]}}
{
  "someField": 123,
  "someArray": [1, 2, 3, { "nested": [1, 2, 3] }]
}
```

you can select from an object with

```
input.someField -> 123
```

or

```
input["someField"] -> 123
```

You select from arrays with

```
input.someArray[0] -> 1
```

and from the end of arrays with

```
input.someArray[-2] -> 3
```

Selectors can be nested as

```
input.someArray[3].nested[2] -> 3
```

Selectors can contain expressions

```
input.someArray[1 + 1] -> 3
```

## Functions

The hosted extractor mapping language contains a set of predefined functions, which can be used to transform the input in other ways.

For example,

```
float("1.4") -> 1.4
```

will try to transform the input from a string to a number, which may fail.

Any function can also be called *postfix*, as a method on a value, so you could instead write

```
"1.4".float() -> 1.4
```

This is especially useful when dealing with chained operations.

See also [Functions](/cdf/integration/guides/extraction/hosted_extractors/built_in_functions).

## Lambda expressions

Some functions can take user defined functions as arguments, such as `map`, `reduce`, or `filter`. To create the functions for these, use *Lambda notation*: `argument => return`.

If the function takes no arguments, use `()` as the input to the function. If a function takes multiple values, denote them as a tuple: `(arg1, arg2)`.

### Examples

If we want to turn the list `[1, 2, 3, 4]` into `[2, 4, 6, 8]` we can use `map` to apply a function to each member of the list, and write a lambda function that doubles each value:

```
[1, 2, 3, 4].map(number => number * 2) -> [2, 4, 6, 8]
```

If you want to remove all `null`s from a list, use the `filter` function, and write a lambda function that returns true if the value is the `null` type using the `is` operator:

```
[0, 1, 2, 3, 4, null, 5].filter(item => !(item is "null")) -> [0, 1, 2, 3, 4, 5]
```

To sum all the numbers from 1 through 10, use the `reduce` function to iteratively add the next member of the list to an aggregate:

```
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].reduce((sum, next) => sum + next, 0) -> 110
```

## Operators

The operators take one or two inputs and output some value. The operators are:

### Plus

`1 + 2 + 3 -> 6`

Adds two numbers together.

### Minus

`1 - 2 - 3 -> -4`

Subtracts a number from another.

### Multiply

`2 * 3 -> 6`

Multiplies two numbers.

### Divide

`3 / 2 -> 1.5`

Divides one number by another.

### And

`true && false -> false`

Boolean AND, returns `true` if the inputs are both not `null` or `false`.

### Or

`true || false -> true`

Boolean OR, returns `true` if either input is not `null` or `false`.

### Equals

`1 == 2 -> false`

Checks for exact equality. The inputs must be the same type, or this will be `false`.

### Not equals

`1 != 2 -> true`

Checks for inequality.

### Greater than

`2 > 3 -> false`

Checks if the first number is greater than the second number.

### Greater than or equal

`2 >= 3 -> false`

Checks if the first number is greater than or equal to the second number.

### Less than

`2 < 3 -> true`

Checks if the first number is less than the second number.

### Less than

`2 <= 3 -> true`

Checks if the first number is less than or equal to the second number.

### Modulo

`5 % 2 -> 1`

Computes the modulus, or remainder, of the first argument divided by the second argument.

### Is

`5 is float`

This is the type check operator, used to check if the first argument is the type given by the second argument. The valid types are

* `null`
* `object`
* `array`
* `string`
* `number`
* `float`
* `int`
* `bool`

Any `float` or `int` is also `number`.

## If expressions

You can use functional-style `if` expressions. For example

```
if 2 > 3 {
  "hello"
} else if 2 == 2 {
  "world"
} else {
  "goodbye"
}
```

will return `"world"`. There is an `if` function as well, but using expressions usually results in cleaner code.

## Objects

You can create JSON objects with familiar JSON syntax:

```
{
  "hello": 123,
  "test": input.something
}
```

These objects can be accessed, just like input variables:

`{ "hello": 123 }.hello`

You can concat objects using the `...` operator:

```
{
  "test": 123,
  ...{
    "hello": "world"
  },
  ...{
    "world": "hello"
  }
}
```

will yield the object

```
{
  "test": 123,
  "hello": "world",
  "world": "hello"
}
```

Object keys can also be expressions:

`{ concat("he", "llo"): "world" }`

will yield an object

`{ "hello": "world" }`

## Arrays

Arrays can be created using a JSON syntax:

`[1, 2, 3]`

You can access arrays using brackets, just like with inputs:

`[1, 2, 3][0] -> 1`

Arrays also support the `...` operator:

```
[
  1,
  ...[2, 3],
  ...[4, 5]
]
```

will yield

`[1, 2, 3, 4, 5]`

## Macros

Define your own reusable macros at the top of your mapping file:

```
#my_macro := (a, b) => a + b;

// Then use it later in the mapping expression
my_macro(3, 4) -> 7
```

Macros may call each other, but may not form loops.

```
#my_macro := (a, b) => my_macro(1, 2); // Illegal

#my_macro_1 := a => a + 1;
#my_macro_2 := b => my_macro_1(b) + 1; // Legal
```

Avoid using the same argument name in macros that call each other. In the example above, it wouldn't be allowed to have `my_macro_1` take an argument named `b`.

## Variables

You can define reusable intermediate variables at the top of lambdas or at the top of the expression:

```
#thing := 1 + 1;
#other_thing := floor(thing);

[1, 2, 3].map(a =>
  #intermediary := a + other_thing;
  intermediary
)
```

Variables may not overlap with each other or with lambda variables.

## Template strings

Template strings allow you to easily construct dynamic strings, instead of having to
rely on the `concat` method:

```
$"Math: 1 + 1 = {1 + 1}, {'nested string'}"
```

would result in `"Math: 1 + 1 = 2, nested string"`. You can escape `{` and `}` using `{{` and `}}`, for example:

```
$"Hello: {{World}}"
```

would produce `"Hello {World}"`.
