# Understanding recursion in JSONata

* [Explanation](#explanation)&#x20;
  * [Function Definition](#id-1.-definicao-da-funcao)&#x20;
  * [Applying the Function](#id-2.-applying-the-function)
* [Incrementing the Example](#enhancing-the-example)&#x20;
  * [JSON Input Example](#json-input-example)&#x20;
  * [Expanded Function and Query ](#funcao-expandida-e-consulta)
  * [Explanation](#explanation-1)
  * [Example output](#example-output)
* [Examples and Use Cases](#exemplos-adicionais-e-casos-de-uso)&#x20;
  * [Example with Siblings ](#exemplo-com-irmaos)
  * [JSON Input](#json-de-entrada)&#x20;
  * [Expanded Function and Query to Handle Siblings](#funcao-expandida-e-consulta-para-tratar-irmaos)&#x20;
* [Conclusion](#conclusao)

Next, we'll present an example that defines recursion to navigate and transform a JSON structure. This article will detail the initial example and expand it with additional explanations, practical examples and use cases, providing a comprehensive understanding of the application of recursion in JSONata.

```json
(
   $person := function($node) { $node.{"n": Name, "p":$person(Parent.Person)}};


   {
       "Person": Person ~> $person($)
   }
)

```

## Explanation

### 1. Function Definition: <a href="#id-1.-definicao-da-funcao" id="id-1.-definicao-da-funcao"></a>

```
$person := function($node) { $node.{"n": Name, "p":$person(Parent.Person)}};
```

The line above defines a recursive function called $person. The function takes a node ($node) as an argument. It returns an object containing:

* "n": Name - The Name property of the current node.
* "p": $person(Parent.Person) - The result of calling the $person function on the Parent.Person property of the current node, allowing for recursive navigation.

### 2. Applying the Function

```
 {
    "Person": Person ~> $person($)
}

```

This part applies the **$person** function to the "**Person**" field in the current context (denoted by $). The \~> operator pipes the "**Person**" field through the **$person** function.

### Enhancing the Example

Let's enhance the example by adding more fields for transformation and navigating through more deeply nested JSON structures. Consider the following more complex JSON structure:

#### JSON Input Example&#x20;

```json
{
 "Person": {
   "Name": "João",
   "Age": 30,
   "Parent": {
     "Person": {
       "Name": "Maria",
       "Age": 55,
       "Parent": {
         "Person": {
           "Name": "Roberto",
           "Age": 80
         }
       }
     }
   }
 }
}

```

#### Expanded Function and Query <a href="#funcao-expandida-e-consulta" id="funcao-expandida-e-consulta"></a>

Let's modify the function to include the "**Age**" property and handle cases where "**Parent**" may be absent.

```json
(
   $person := function($node) {
   $node.{
           "n": Name,
           "a": Age,
           "p": $exists($person(Parent.Person)) ? $person(Parent.Person) : null
       }
   };


   {
       "Person": Person ~> $person($)
   }
)


```

#### Explanation

* The modified function now includes **"a": Age** to capture each person's age.&#x20;
* The ternary operator ($exists($person(Parent.Person)) ? ... : null) ensures the function returns "null" if the node is not present, preventing errors when navigating the hierarchy.

#### Example Output

Applying the expanded query to the input JSON example will result in:

```json
{
"Person": {
  "n": "João",
  "a": 30,
  "p": {
    "n": "Maria",
    "a": 55,
    "p": {
      "n": "Roberto",
      "a": 80,
      "p": null
    }
  }
}
}

```

### Additional Example & Use Cases  <a href="#exemplos-adicionais-e-casos-de-uso" id="exemplos-adicionais-e-casos-de-uso"></a>

#### Example with Siblings <a href="#exemplo-com-irmaos" id="exemplo-com-irmaos"></a>

Let's consider an example where each person can have siblings.

#### **JSON** Input <a href="#json-de-entrada" id="json-de-entrada"></a>

```json
{
 "Person": {
   "Name": "João",
   "Age": 30,
   "Siblings": [
     {
       "Name": "Ana",
       "Age": 25
     },
     {
       "Name": "Alex",
       "Age": 28
     }
   ],
   "Parent": {
     "Person": {
       "Name": "Maria",
       "Age": 55,
       "Parent": {
         "Person": {
           "Name": "Roberto",
           "Age": 80
         }
       }
     }
   }
 }
}

```

#### Expanded Function and Query to Handle Siblings <a href="#funcao-expandida-e-consulta-para-tratar-irmaos" id="funcao-expandida-e-consulta-para-tratar-irmaos"></a>

We can expand our role even further to include brothers:

```json
(
   $person := function($node) {
   $node.{
           "n": Name,
           "a": Age,
           "s": $exists($person(Siblings)) ? $person(Siblings) : null,
           "p": $exists($person(Parent.Person)) ? $person(Parent.Person) : null
       }
   };


   {
       "Person": Person ~> $person($)
   }
)

```

**Explanation**

* The line "s": $exists($person(Siblings)) ? $person(Siblings) : null maps the Siblings array and transforms each sibling into an object.

**Example Output**

Applying the expanded query to the input JSON example will result in:

```json
{
 "Person": {
   "n": "João",
   "a": 30,
   "s": [
     {
       "n": "Ana",
       "a": 25,
       "s": null,
       "p": null
     },
     {
       "n": "Alex",
       "a": 28,
       "s": null,
       "p": null
     }
   ],
   "p": {
     "n": "Maria",
     "a": 55,
     "s": null,
     "p": {
       "n": "Roberto",
       "a": 80,
       "s": null,
       "p": null
     }
   }
 }
}

```

### Conclusion <a href="#conclusao" id="conclusao"></a>

The recursive function in JSONata provides a powerful way to navigate and transform nested JSON structures. By defining and applying such functions, you can traverse hierarchical data, handle optional fields and even map arrays to produce complex, automated transformations.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.skyone.cloud/english/skyone-studio/how-to/understanding-recursion-in-jsonata.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
