# Tips for Dealing with Data

{% hint style="info" %}
Don't forget to turn on ✅ [Evaluating as JS expression](/template-system/evaluating-as-js-expression.md) option
{% endhint %}

<figure><img src="/files/JDquyDazELmTLbFUp00R" alt=""><figcaption><p>Example of using JS-expression in the <a href="/pages/-M6ic7XcU2jGl8VdmD2C">Edit object</a> step</p></figcaption></figure>

## 🔢 Dealing with numbers and decimals

### Getting a random number \[1–100]

```javascript
Math.floor(Math.random()*100)
```

### Changing the number of digits to appear after the decimal point

```javascript
parseFloat('{{decimal_value}}').toFixed(2) // 2 digits after the point
//
// e.g.
// parseFloat('12.438324').toFixed(2) returns 12.43
```

## 🔤 Dealing with strings

### Converting multiline text to an array of lines

For instance, if you receive a `{{text}}` field (type: string) from a Telegram bot in multiple lines and want to process each line separately, here's how you can do it:

```javascript
'{{text}}'.replace(/\n/g, ',') 
// this is string with lines, separated by commas (you may use any other character)
// in this way arrays in the platform are stored
// e.g.
// {{text}} = 
// Good fortune? The fact is
// The more that you practise
// The harder you sweat
// The luckier you get
// 
// result will be:
// Good fortune? The fact is,The more that you practise,The harder you sweat,The luckier you get

'{{text}}'.replace(/\n/g, ',').split(',') // this returns js-array

'{{text}}'.replace(/\n/g, ',').split(',')[0] // this returns the first line
'{{text}}'.replace(/\n/g, ',').split(',')[1] // this returns the second line
```

### Getting md5 hash

```javascript
$D.md5('{{string}}')
//$D.md5('12345') returns 827ccb0eea8a706c4c34a16891f84e7b
```

### Generating a random string (password)

```javascript
Math.random().toString(36).slice(-12) // 12 characters string
```

## 🛒 Dealing with arrays

{% hint style="info" %}
Directual stores **array** and **arrayLink** types as **strings**
{% endhint %}

### Converting a string (Directual array or arrayLink) into a JS-Array value

```javascript
'{{array}}'.split(',')
// {{array}} is a field with Directual type array
// 
// e.g. {{array}} = 1,-2,a
// '{{array}}'.split(',') returns [1,-2,a]
```

### Saving a JS array to a Directual array

```javascript
const array = ["a","b","c"] // standard JS array
// if you want to save it to Directual array, you need:
array.join(",")
// as soon as Directual stores array and arrayLink types as strings
```

### Counting elements of an array

```javascript
// basically, the expression is
'{{array}}'.split(',').length
// {{array}} is a field with Directual type array

// BUT! if {{array}} is empty, the expression above returns 1,
// so the expression should be the following:
'{{array}}' ? '{{array}}'.split(',').length : 0
```

### Getting an element from an array with number N

```javascript
'{{array}}'.split(',')[N]
// {{array}} is a field with type Array.
// 
// e.g. {{a}} = a,b,c
// '{{a}}'.split(',')[1] returns b
```

### Getting a random element from an array

```javascript
'{{array}}'.split(',')[Math.floor(Math.random()*'{{array}}'.split(',').length)]
// here we counts N = number of elements in array, 
// get the random number [0–N] and pick the random element
```

### Adding an element into an array while preventing duplicates

`$D.concat` is a specific [Directual JS-function](/javascript-sdk/internal-usdd-methods.md)

```javascript
$D.concat('{{array}}', 'new element')
// or
$D.concat('{{array}}', '{{other_field}}')
// even or
$D.concat('{{array}}', '{{other_field_1}},{{other_field_2}}')
//
// e.g.
// $D.concat('', '3') returns 3
// $D.concat('1,2', '1,2,3') returns 1,2,3
// $D.concat('1,2,3', '3,4') returns 1,2,3,4
// $D.concat('1,2,3', '3') returns 1,2,3
```

![Example of applying $D.concat in 'Edit object' scenario step](/files/-M6Uvheor9K40YUqOi4l)

### Removing an element from an array

`$D.splice` is a specific [Directual JS-function](/javascript-sdk/internal-usdd-methods.md)

```javascript
$D.splice('{{array}}', 'removed element')
// or
$D.splice('{{array}}', '{{other_field}}')
// even or
$D.splice('{{array}}', '{{other_field_1}},{{other_field_2}}')
//
// e.g.
// $D.splice('', '3') returns ''
// $D.splice('1,2', '1,2,3') returns 3
// $D.splice('1,2,3', '3,4') returns 1,2
// $D.splice('1,2,3', '3') returns 1,2
```

### Applying an array iterator `map()`

JS iterators are more applicable in [JS SDK step](/scenarios/editing-scenarios/action-steps/js-sdk-step.md). However, `.map` iterator can be useful in regular steps as well. This method adits all the elements of a given array.&#x20;

```javascript
// e.g. we want to add ' is the best' to every element of {{array}}.
// Here is the expression for that:
'{{array}}'.split(',').map(function(element) 
   {return element + ' is the best'}).join(',')
   
// let {{array}} was "Jhon,Ivan,Anna"
// the expression will return
// Jhon is the best,Ivan is the best,Anna is the Best
```

### Applying an array iterator `reduce()` for calculating average

JS iterators are more applicable in [JS SDK step](/scenarios/editing-scenarios/action-steps/js-sdk-step.md). However, `.reduce` iterator can be useful in regular steps as well.

```javascript
"{{array}}".split(",")
    .reduce(function(acc, curr) 
        {return parseInt(acc) + parseInt(curr)}) 
    / "{{array}}".split(",").length
    
// e.g. for {{array}} == 1,2,5,0,-4,12 
// that expression returns 2.666667
```

### Arrays intersection (using `lodash`)

[Lodash documentation](https://lodash.com/docs/3.10.1#intersection) on `_.intersection`

```
_.intersection("{{array1}}".split(","), "{{array2}}".split(","));
```

## 📅 Dealing with dates

### Getting current time

The method `(new Date()).toISOString()` returns a JS-date-object with current time. This method is more useful than `now`, because we can compose complex JS-expressions in a one step using `(new Date()).toISOString()`

```javascript
(new Date()).toISOString()
// returns current Coordinated Universal Time (UTC)
// (new Date()).toISOString() === now === moment().toISOString()
```

### Converting date format

Learn more about [date formatting](/data/data-types/formatting-date-time-data.md)

{% hint style="warning" %}
$D.date.format returns string data, so you can't save the result into a field type of date.
{% endhint %}

```javascript
$D.date.format('{{date_1}}','MMMM dd, YYYY')
// 
// e.g. $D.date.format('2020-05-20T18:14:11.000Z','MMMM dd, YYYY') 
// returns May 20, 2020
//
$D.date.format($D.date.new(),'dd/MM/YYYY')
// returns today in a certain format e.g. 07.01.2021
```

### Converting into timestamp

`Unix timestamp` format is a way to track time as a running total of seconds. This count starts at the Unix Epoch on January 1st, 1970 at UTC.

```javascript
((new Date('{{date}}')).getTime()/1000).toString()
//
// e.g {{date}} == 2020-11-12T00:00:00
// ((new Date('{{date}}')).getTime()/1000).toString() returns 1605139200 seconds
```

### Parsing date

```javascript
$D.date.parse('{{formatted_date}}',dateFormat)
// 
// e.g. $D.date.parse('10-03-2020','dd-MM-YYY') returns 2020-03-10T00:00:00.000Z
```

You can compose an expression using both $D.date parse and $D.date.format to convert a format date from one to another:

```javascript
$D.date.format($D.date.parse('10-03-2020','dd-MM-YYY'),'MMMM dd, YYYY')
// here we've converted 10-03-2020 into March 10, 2020
```

### Incrementing date

If you want to add minutes/hours/days/weeks to the date, here is the way

{% hint style="info" %}
You can also [use MomentJS](/template-system/tips-for-working-with-data.md#applying-momentjs) for that
{% endhint %}

```javascript
//adding {{minutes}} minutes
(new Date((new Date('{{date}}')).getTime() + ('{{minutes}}' * 60 * 1000))).toISOString()

//adding {{hours}} hours
(new Date((new Date('{{date}}')).getTime() + ('{{hours}}' * 60 * 60 * 1000))).toISOString()

//adding {{days}} days
(new Date((new Date('{{date}}')).getTime() + ('{{days}}' * 60 * 60 * 24 * 1000))).toISOString()

//adding {{weeks}} weeks
(new Date((new Date('{{date}}')).getTime() + ('{{weeks}}' * 7 * 60 * 60 * 24 * 1000))).toISOString()
```

### Creating a unique object for each day

You may need to aggregate statistics for the day into a single object (e.g., counting the quantity of orders or users). A straightforward approach is to create an object with an ID in the format of the date of the day. Here's an example expression for generating such a day-unique ID:

```javascript
$D.date.format($D.date.new(),'dd-MM-YYYY')
// for todays object

$D.date.format('{{today_date}}','dd-MM-YYYY')
// where {{today_date}} is a type of date field
```

![An example of 'Create object' step for creating a 'daily-unique' object](/files/-M6V9KbZdK_y8pECB18I)

{% hint style="info" %}
Don't forget to Save a link (*write a link in the field*) to the new object in order to be able to edit it. Note, that if you create an object with ID while there is an object with such an ID, nothing will be broken. You'll just create a link to that existing object.
{% endhint %}

### Calculating the number of days between two dates

To solve this, use the `getTime()` JS-function, which operates on the Date JS-object and returns Milliseconds since Epoch time. Here are the steps:

* Getting a Date JS-object applying `new Date('{{date}}')` to the field `{{date}}` type of date
* Getting the value in milliseconds since Epoch time applying `.getTime()`
* Calculate the difference between two dates in milliseconds
* Convert milliseconds into days, dividing the result to `(1000*60*60*24)`—1000 milliseconds in a one, second; 60 seconds in a minute; 60 minutes in an hour; and 24 hours in a day

```javascript
Math.floor((($D.date.new().getTime() -
 (new Date('{{date}}')).getTime()))/(1000*60*60*24))
// Calculating the number of days between the current moment and {{date}}

Math.floor((((new Date('{{date_1}}')).getTime() -
 (new Date('{{date_2}}')).getTime()))/(1000*60*60*24))
// Calculating the number of days between {{date_1}} and {{date_2}}
```

N.B Here is a nice article referring to [understanding Date and Time in JavaScript](https://www.digitalocean.com/community/tutorials/understanding-date-and-time-in-javascript)

### Applying MomentJS

You can also use MomentJS library. Check out [MomentJS documentation](https://momentjs.com/docs/).

Example of using MomentJS:

```javascript
moment("{{date}}").add(10, 'days').format('DD-MM-YYYY')

// e.g {{date}} == 2020-11-12T00:00:00
// expression will return 22-11-2020
```

## 🥷 Regular expressions

Directual JS-engine supports Regex-functions. Here are some widespread examples.

{% hint style="info" %}
Tip: use <https://regex101.com/> for composing a correct Regex-expression
{% endhint %}

### Replace

```javascript
"{{text}}".replace(/one/gm, "two") 
// repplaces all the words "one" in the text to "two"
```

### Extract

```javascript
/\+\d{11}/gm.exec("{{text}}") // returns an array of phone numbers found in text
/\+\d{11}/gm.exec("{{text}}")[0] // the first element of an array
/\+\d{11}/gm.exec("{{text}}").join(",") // converts JS-array into Directual-array
```


---

# 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://readme.directual.com/template-system/tips-for-working-with-data.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.
