This article explains different ways merge gates can be used and how to do it.  


If the material below feels inaccessible, we recommend reading part 1 and part 2 on Merge Gates and that you be familiar with the Exaptive Data Model, including the Type System Reference



Merging Data


Concatenation


string + string  --> string (concatenate first and last name)


Input: 

  

x0: "Mike"
x1: "Smith"

  

Expression:

  

x0 + " " +x1

  

Output: 

 

"Mike Smith"

 


string + string + integer = string (concatenate name and age into one readable string)


This uses JavaScript toString() method to convert integer to string. 


Input: 

 

x0: "Mike"
x1: "Smith"
x2: 78

 

Expression:

  

x0 + " " + x1 + ": " + x2.toString()

  

Output:


 

"Mike Smith: 78"

 


Entity Creation


multiset of entities + multiset of entities --> entity (convert two related pricing duffles into one entity for comparison)


Input: 


x0: [
  {
    "High": 104.55, 
    "Ex-Dividend": 0, 
    "Adj. Low": 103.68, 
    "Open": 104.19, 
    "Volume": 27076805, 
    "Adj. Close": 104.19, 
    "Adj. High": 104.55, 
    "Low": 103.68, 
    "Close": 104.19, 
    "Date": "2016-07-29", 
    "Adj. Open": 104.19, 
    "Split Ratio": 1, 
    "Adj. Volume": 27076805, 
    "Stock": "AAPL"
  }
]

x1: [
  {
    "Date": "2016-07-31", 
    "Name": "Bitcoin Market Price USD", 
    "Value": 656.8876125
  }
]

  

Expression:

 

{stockData: x0, bitcoinData: x1}

 

Output:

 

{
  "stockData": [
    {
      "High": 104.55, 
      "Ex-Dividend": 0, 
      "Adj. Low": 103.68, 
      "Open": 104.19, 
      "Volume": 27076805, 
      "Adj. Close": 104.19, 
      "Adj. High": 104.55, 
      "Low": 103.68, 
      "Close": 104.19, 
      "Date": "2016-07-29", 
      "Adj. Open": 104.19, 
      "Split Ratio": 1, 
      "Adj. Volume": 27076805, 
      "Stock": "AAPL"
    }
  ], 
  "bitcoinData": [
    {
      "Date": "2016-07-31", 
      "Name": "Bitcoin Market Price USD", 
      "Value": 656.8876125
    }
  ]
}

 


string + string + integer --> entity (combine all relevant data about an individual into an entity)

 

Input:

 

x0: "Mike"
x1: "Smith"
x2: 78

 


Expression: 

 

{
"first": x0, 
"last": x1, 
"age": x2
}

 


Output:

  

{
"first": "Mike", 
"last": "Smith", 
"age": 78 
}

  


Listify


entity + entity --> list of entities (add two individual's data into one list of entities)


Input:

   

x0: {
  "first": "Mike", 
  "last": "Smith", 
  "age": 78
}

x1: {
  "first": "Lynn", 
  "last": "Williams", 
  "age": 46
}

  

Expression:

 

[x0, x1]

  


Output:

 

[
{
  "first": "Mike", 
  "last": "Smith", 
  "age": 78
}
,
{
  "first": "Lynn", 
  "last": "Williams", 
  "age": 46
}
]

 


Transforming Data


Accessing a Value on an Entity


entity --> integer (get individual's age)


Input:

 

x0: {
  "first": "Mike", 
  "last": "Smith", 
  "age": 78
}

 

Expression:

 

x0.age

 

Output:

    

78  


Using JavaScript's Array.Map() Method


list of entities --> modified list of entities (check if individual qualifies for Social Security)'


Input:

  

[
{
  "first": "Mike", 
  "last": "Smith", 
  "age": 78
}
,
{
  "first": "Lynn", 
  "last": "Williams", 
  "age": 46
}
]

 


Expression:


x0.map(function(obj){
obj.age > 62 ? obj["S.S. Qualified"] = "Yes" : obj["S.S. Qualified"] = "No";
return obj;
})

 

Output:

  

[
{
  "first": "Mike", 
  "last": "Smith", 
  "age": 78, 
  "S.S. Qualified": "Yes"
}
,
{
  "first": "Lynn", 
  "last": "Williams", 
  "age": 46,
  "S.S. Qualified": "No"
}
]

  



list of entities --> modified list of entities (update age in each entity)


Input:

 

[
{
  "first": "Mike", 
  "last": "Smith", 
  "age": 78, 
  "S.S. Qualified": "Yes"
}
,
{
  "first": "Lynn", 
  "last": "Williams", 
  "age": 46,
  "S.S. Qualified": "No"
}
]

 

Expression:

 

x0.map(function(obj){
obj.age += 1;
return obj;
})

 

Output:

 

[
{
  "first": "Mike", 
  "last": "Smith", 
  "age": 79, 
  "S.S. Qualified": "Yes"
}
,
{
  "first": "Lynn", 
  "last": "Williams", 
  "age": 47,
  "S.S. Qualified": "No"
}
]

 


list of entities --> list of strings (get list of user name's)


Input:

 

[
{
  "first": "Mike", 
  "last": "Smith", 
  "age": 78, 
  "S.S. Qualified": "Yes"
}
,
{
  "first": "Lynn", 
  "last": "Williams", 
  "age": 46,
  "S.S. Qualified": "No"
}
]

 

Expression:

 

x0.map(function(obj){
var name = obj.first+" "+obj.last;
return name;
})

 

Output:

 

["Mike Smith", "Lynn Williams"]





Advanced Examples


These examples use a single use-case - combining several parts of a string to form a URL - to explain various advanced concepts like inline Javascript code and resetting timestamps.



Output a single entity of the form {host, port, path} whenever any of the input changes. It will output even if some of the values are not set.

{
    inputs: ["host", "port", "path"],
    output: "data"
}

 

Output the url whenever any of the input changes.

{
    inputs: ["host", "port", "path"],
    output: "url",

    expression: "'http://' + host + ':' + port + '/' + path"
}

 

Multiple statements and variables: You can enter multiple statements and use variabes by chaining ,. In this case, the last expression is the value of the entire expression. This is nothing specific to a gate, but just a feature of JavaScript expressions. Although discouraged, it is sometimes necessary, as JavaScript is not entirely a functional language:

{
    inputs: ["host", "port", "path"],
    output: "url",

    expression: "x = 'http://' + host, x += ':' + port, x += '/' + path, x",
}

 

Reset: Output the url whenenver any of the input changes, but only if the inputs are all non-empty

{
    inputs: ["host", "port", "path"],
    output: "url",
    expression: "'http://' + host + ':' + port + '/' + path",
    condition: "host && port && path"
}

 

Reset: Output the url only when all the inputs are set. Never reuse any value.

{
    inputs: ["host", "port", "path"],
    output: "url",
    expression: "'http://' + host + ':' + port + '/' + path",
    condition: "timeOf('host') && timeOf('port') && timeOf('path')",
    resetOnOutput: ["host", "port", "path"],

    // same effect
    resetOnOutput: true
}

 

Reset: Output the url only when all the inputs are set, and reuse the host and port.

{
    inputs: ["host", "port", "path"],
    output: "url",
    expression: "'http://' + host + ':' + port + '/' + path",
    condition: "timeOf('host') && timeOf('port') && timeOf('path')",
    resetOnOutput: ["path"],
}

 

Reset: Output the url only when all the inputs are set. Reuse the host and port, but discard the port if the host changes. This is useful to prevent it from using the wrong port.

{
    inputs: ["host", "port", "path"],
    output: "url",
    expression: "'http://' + host + ':' + port + '/' + path",
    condition: "timeOf('host') && timeOf('port') && timeOf('path')",
    resetOnOutput: ["path"],
    resetOnInput: {"host": ["port"]}
}

 

Reset: Output only when "release" is explicitly hit.

{
    inputs: ["host", "port", "path", "release"],
    output: "url",
    expression: "'http://' + host + ':' + port + '/' + path",
    condition: "timeOf("release")",
    resetOnOutput: ["release"],
}

 

Debug: Break every time the expression or condition is evaluated.

{
    inputs: ["host", "port", "path"],
    output: "url",
    debug: "host === 'http://exaptive.com'",
    expression: "x = 'http://' + host, x += ':' + port, x += '/' + path, x",
}