-
Notifications
You must be signed in to change notification settings - Fork 6
/
higher-order-functions.html
147 lines (140 loc) · 20.2 KB
/
higher-order-functions.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><title>Higher order functions · JSONata</title><meta name="viewport" content="width=device-width, initial-scale=1.0"/><meta name="generator" content="Docusaurus"/><meta name="description" content="## `$map()`"/><meta name="docsearch:version" content="2.0.0"/><meta name="docsearch:language" content="en"/><meta property="og:title" content="Higher order functions · JSONata"/><meta property="og:type" content="website"/><meta property="og:url" content="http://docs.jsonata.org/"/><meta property="og:description" content="## `$map()`"/><meta name="twitter:card" content="summary"/><link rel="shortcut icon" href="/img/jsonata-button.png"/><link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/default.min.css"/><script type="text/javascript" src="https://buttons.github.io/buttons.js"></script><script type="text/javascript" src="/js/jsonata-examples.js"></script><script src="/js/scrollSpy.js"></script><link rel="stylesheet" href="/css/main.css"/><script src="/js/codetabs.js"></script></head><body class="sideNavVisible separateOnPageNav"><div class="fixedHeaderContainer"><div class="headerWrapper wrapper"><header><a href="/"><img class="logo" src="/img/jsonata-button.png" alt="JSONata"/><h2 class="headerTitleWithLogo">JSONata</h2></a><a href="/versions"><h3>2.0.0</h3></a><div class="navigationWrapper navigationSlider"><nav class="slidingNav"><ul class="nav-site nav-site-internal"><li class="siteNavGroupActive"><a href="/overview" target="_self">Docs</a></li><li class=""><a href="http://try.jsonata.org" target="_self">Try</a></li><li class=""><a href="https://github.com/jsonata-js/jsonata" target="_self">GitHub</a></li><li class=""><a href="https://www.npmjs.com/package/jsonata" target="_self">NPM</a></li></ul></nav></div></header></div></div><div class="navPusher"><div class="docMainWrapper wrapper"><div class="docsNavContainer" id="docsNav"><nav class="toc"><div class="toggleNav"><section class="navWrapper wrapper"><div class="navBreadcrumb wrapper"><div class="navToggle" id="navToggler"><div class="hamburger-menu"><div class="line1"></div><div class="line2"></div><div class="line3"></div></div></div><h2><i>›</i><span>Function Library</span></h2><div class="tocToggler" id="tocToggler"><i class="icon-toc"></i></div></div><div class="navGroups"><div class="navGroup"><h3 class="navGroupCategoryTitle">Getting Started</h3><ul class=""><li class="navListItem"><a class="navItem" href="/overview">Overview</a></li><li class="navListItem"><a class="navItem" href="/using-nodejs">In NodeJS</a></li><li class="navListItem"><a class="navItem" href="/using-browser">In a Web Page</a></li></ul></div><div class="navGroup"><h3 class="navGroupCategoryTitle">Language Guide</h3><ul class=""><li class="navListItem"><a class="navItem" href="/simple">Simple Queries</a></li><li class="navListItem"><a class="navItem" href="/predicate">Predicate Queries</a></li><li class="navListItem"><a class="navItem" href="/expressions">Functions and Expressions</a></li><li class="navListItem"><a class="navItem" href="/construction">Result Structures</a></li><li class="navListItem"><a class="navItem" href="/composition">Query Composition</a></li><li class="navListItem"><a class="navItem" href="/sorting-grouping">Sorting, Grouping and Aggregation</a></li><li class="navListItem"><a class="navItem" href="/processing">Processing Model</a></li><li class="navListItem"><a class="navItem" href="/programming">Functional Programming</a></li><li class="navListItem"><a class="navItem" href="/regex">Regular Expressions</a></li><li class="navListItem"><a class="navItem" href="/date-time">Date/Time Processing</a></li></ul></div><div class="navGroup"><h3 class="navGroupCategoryTitle">Operators</h3><ul class=""><li class="navListItem"><a class="navItem" href="/path-operators">Path Operators</a></li><li class="navListItem"><a class="navItem" href="/numeric-operators">Numeric Operators</a></li><li class="navListItem"><a class="navItem" href="/comparison-operators">Comparison Operators</a></li><li class="navListItem"><a class="navItem" href="/boolean-operators">Boolean Operators</a></li><li class="navListItem"><a class="navItem" href="/other-operators">Other Operators</a></li></ul></div><div class="navGroup"><h3 class="navGroupCategoryTitle">Function Library</h3><ul class=""><li class="navListItem"><a class="navItem" href="/string-functions">String Functions</a></li><li class="navListItem"><a class="navItem" href="/numeric-functions">Numeric Functions</a></li><li class="navListItem"><a class="navItem" href="/aggregation-functions">Aggregation Functions</a></li><li class="navListItem"><a class="navItem" href="/boolean-functions">Boolean Functions</a></li><li class="navListItem"><a class="navItem" href="/array-functions">Array Functions</a></li><li class="navListItem"><a class="navItem" href="/object-functions">Object Functions</a></li><li class="navListItem"><a class="navItem" href="/date-time-functions">Date/Time Functions</a></li><li class="navListItem navListItemActive"><a class="navItem" href="/higher-order-functions">Higher Order Functions</a></li></ul></div><div class="navGroup"><h3 class="navGroupCategoryTitle">Extending JSONata</h3><ul class=""><li class="navListItem"><a class="navItem" href="/embedding-extending">Embedding and Extending JSONata</a></li><li class="navListItem"><a class="navItem" href="/contributing">Community and Contributing</a></li></ul></div></div></section></div><script>
var coll = document.getElementsByClassName('collapsible');
var checkActiveCategory = true;
for (var i = 0; i < coll.length; i++) {
var links = coll[i].nextElementSibling.getElementsByTagName('*');
if (checkActiveCategory){
for (var j = 0; j < links.length; j++) {
if (links[j].classList.contains('navListItemActive')){
coll[i].nextElementSibling.classList.toggle('hide');
coll[i].childNodes[1].classList.toggle('rotate');
checkActiveCategory = false;
break;
}
}
}
coll[i].addEventListener('click', function() {
var arrow = this.childNodes[1];
arrow.classList.toggle('rotate');
var content = this.nextElementSibling;
content.classList.toggle('hide');
});
}
document.addEventListener('DOMContentLoaded', function() {
createToggler('#navToggler', '#docsNav', 'docsSliderActive');
createToggler('#tocToggler', 'body', 'tocActive');
var headings = document.querySelector('.toc-headings');
headings && headings.addEventListener('click', function(event) {
var el = event.target;
while(el !== headings){
if (el.tagName === 'A') {
document.body.classList.remove('tocActive');
break;
} else{
el = el.parentNode;
}
}
}, false);
function createToggler(togglerSelector, targetSelector, className) {
var toggler = document.querySelector(togglerSelector);
var target = document.querySelector(targetSelector);
if (!toggler) {
return;
}
toggler.onclick = function(event) {
event.preventDefault();
target.classList.toggle(className);
};
}
});
</script></nav></div><div class="container mainContainer docsContainer"><div class="wrapper"><div class="post"><header class="postHeader"><a class="edit-page-link button" href="https://github.com/jsonata-js/jsonata/edit/master/docs/higher-order-functions.md" target="_blank" rel="noreferrer noopener">Edit</a><h1 id="__docusaurus" class="postHeaderTitle">Higher order functions</h1></header><article><div><span><h2><a class="anchor" aria-hidden="true" id="map"></a><a href="#map" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><code>$map()</code></h2>
<p><strong>Signature:</strong> <code>$map(array, function)</code></p>
<p>Returns an array containing the results of applying the <code>function</code> parameter to each value in the <code>array</code> parameter.</p>
<p>The function that is supplied as the second parameter must have the following signature:</p>
<p><code>function(value [, index [, array]])</code></p>
<p>Each value in the input array is passed in as the first parameter in the supplied function. The index (position) of that value in the input array is passed in as the second parameter, if specified. The whole input array is passed in as the third parameter, if specified.</p>
<p><strong>Examples</strong></p>
<ul>
<li><code>$map([1..5], $string)</code> => <code>["1", "2", "3", "4", "5"]</code></li>
</ul>
<p>With user-defined (lambda) function:</p>
<pre><code class="hljs">$map(Email.address, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">($v, $i, $a)</span> </span>{
<span class="hljs-string">'Item '</span> & ($i+<span class="hljs-number">1</span>) & <span class="hljs-string">' of '</span> & $count($a) & <span class="hljs-string">': '</span> & $v
})
</code></pre>
<p>evaluates to:</p>
<pre><code class="hljs">[
<span class="hljs-string">"Item 1 of 4: fred.smith@my-work.com"</span>,
<span class="hljs-string">"Item 2 of 4: fsmith@my-work.com"</span>,
<span class="hljs-string">"Item 3 of 4: freddy@my-social.com"</span>,
<span class="hljs-string">"Item 4 of 4: frederic.smith@very-serious.com"</span>
]
</code></pre>
<h2><a class="anchor" aria-hidden="true" id="filter"></a><a href="#filter" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><code>$filter()</code></h2>
<p><strong>Signature:</strong> <code>$filter(array, function)</code></p>
<p>Returns an array containing only the values in the <code>array</code> parameter that satisfy the <code>function</code> predicate (i.e. <code>function</code> returns Boolean <code>true</code> when passed the value).</p>
<p>The function that is supplied as the second parameter must have the following signature:</p>
<p><code>function(value [, index [, array]])</code></p>
<p>Each value in the input array is passed in as the first parameter in the supplied function. The index (position) of that value in the input array is passed in as the second parameter, if specified. The whole input array is passed in as the third parameter, if specified.</p>
<p><strong>Example</strong>
The following expression returns all the products whose price is higher than average:</p>
<pre><code class="hljs">$filter(Account.Order.Product, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">($v, $i, $a)</span> </span>{
$v.Price > $average($a.Price)
})
</code></pre>
<h2><a class="anchor" aria-hidden="true" id="single"></a><a href="#single" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><code>$single()</code></h2>
<p><strong>Signature:</strong> <code>$single(array, function)</code></p>
<p>Returns the one and only one value in the <code>array</code> parameter that satisfy the <code>function</code> predicate (i.e. <code>function</code> returns Boolean <code>true</code> when passed the value). Throws an exception if the number of matching values is not exactly one.</p>
<p>The function that is supplied as the second parameter must have the following signature:</p>
<p><code>function(value [, index [, array]])</code></p>
<p>Each value in the input array is passed in as the first parameter in the supplied function. The index (position) of that value in the input array is passed in as the second parameter, if specified. The whole input array is passed in as the third parameter, if specified.</p>
<p><strong>Example</strong>
The following expression the product in the order whose SKU is <code>"0406654608"</code>:</p>
<pre><code class="hljs">$single(Account.Order.Product, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">($v, $i, $a)</span> </span>{
$v.SKU = <span class="hljs-string">"0406654608"</span>
})
</code></pre>
<h2><a class="anchor" aria-hidden="true" id="reduce"></a><a href="#reduce" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><code>$reduce()</code></h2>
<p><strong>Signature:</strong> <code>$reduce(array, function [, init])</code></p>
<p>Returns an aggregated value derived from applying the <code>function</code> parameter successively to each value in <code>array</code> in combination with the result of the previous application of the function.</p>
<p>The <code>function</code> must accept at least two arguments, and behaves like an infix operator between each value within the <code>array</code>. The signature of this supplied function must be of the form:</p>
<p><code>myfunc($accumulator, $value[, $index[, $array]])</code></p>
<p><strong>Example</strong></p>
<pre><code class="hljs">(
$product := <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">($i, $j)</span></span>{$i * $j};
$reduce([<span class="hljs-number">1.</span><span class="hljs-number">.5</span>], $product)
)
</code></pre>
<p>This multiplies all the values together in the array <code>[1..5]</code> to return <code>120</code>.</p>
<p>If the optional <code>init</code> parameter is supplied, then that value is used as the initial value in the aggregation (fold) process. If not supplied, the initial value is the first value in the <code>array</code> parameter.</p>
<h2><a class="anchor" aria-hidden="true" id="sift"></a><a href="#sift" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><code>$sift()</code></h2>
<p><strong>Signature:</strong> <code>$sift(object, function)</code></p>
<p>Returns an object that contains only the key/value pairs from the <code>object</code> parameter that satisfy the predicate <code>function</code> passed in as the second parameter.</p>
<p>If <code>object</code> is not specified, then the context value is used as the value of <code>object</code>. It is an error if <code>object</code> is not an object.</p>
<p>The function that is supplied as the second parameter must have the following signature:</p>
<p><code>function(value [, key [, object]])</code></p>
<p>Each value in the input object is passed in as the first parameter in the supplied function. The key (property name) of that value in the input object is passed in as the second parameter, if specified. The whole input object is passed in as the third parameter, if specified.</p>
<p><strong>Example</strong></p>
<pre><code class="hljs"><span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">Account</span>.</span><span class="hljs-module"><span class="hljs-identifier">Order</span>.</span><span class="hljs-module"><span class="hljs-identifier">Product</span>.</span></span><span class="hljs-constructor">$sift(<span class="hljs-params">function</span>($<span class="hljs-params">v</span>, $<span class="hljs-params">k</span>)</span> {$k ~> /^Product/})
</code></pre>
<p>This sifts each of the <code>Product</code> objects such that they only contain the fields whose keys start with the string "Product" (using a regex). This example returns:</p>
<pre><code class="hljs">[
{
<span class="hljs-attr">"Product Name"</span>: <span class="hljs-string">"Bowler Hat"</span>,
<span class="hljs-attr">"ProductID"</span>: <span class="hljs-number">858383</span>
},
{
<span class="hljs-attr">"Product Name"</span>: <span class="hljs-string">"Trilby hat"</span>,
<span class="hljs-attr">"ProductID"</span>: <span class="hljs-number">858236</span>
},
{
<span class="hljs-attr">"Product Name"</span>: <span class="hljs-string">"Bowler Hat"</span>,
<span class="hljs-attr">"ProductID"</span>: <span class="hljs-number">858383</span>
},
{
<span class="hljs-attr">"ProductID"</span>: <span class="hljs-number">345664</span>,
<span class="hljs-attr">"Product Name"</span>: <span class="hljs-string">"Cloak"</span>
}
]
</code></pre>
</span></div></article></div><div class="docs-prevnext"><a class="docs-prev button" href="/date-time-functions"><span class="arrow-prev">← </span><span>Date/Time Functions</span></a><a class="docs-next button" href="/embedding-extending"><span>Embedding and Extending JSONata</span><span class="arrow-next"> →</span></a></div></div></div><nav class="onPageNav"><ul class="toc-headings"><li><a href="#map"><code>$map()</code></a></li><li><a href="#filter"><code>$filter()</code></a></li><li><a href="#single"><code>$single()</code></a></li><li><a href="#reduce"><code>$reduce()</code></a></li><li><a href="#sift"><code>$sift()</code></a></li></ul></nav></div><footer class="nav-footer" id="footer"><section class="sitemap"><a href="/" class="nav-home"><img src="/img/jsonata-white-167.png" alt="JSONata"/></a><div><h5>JSONata</h5><a href="http://jsonata.org" target="_blank" rel="noreferrer noopener">JSON query and<br/>transformation language</a><a href="http://try.jsonata.org" target="_blank" rel="noreferrer noopener">Go play in the<br/>JSONata Exerciser</a></div><div><h5>Community</h5><a href="https://stackoverflow.com/questions/tagged/jsonata" target="_blank" rel="noreferrer noopener">Stack Overflow</a><a href="https://jsonata.slack.com/">Project Chat</a><a href="https://twitter.com/" target="_blank" rel="noreferrer noopener">Twitter</a></div><div><h5>More</h5><a href="https://github.com/jsonata-js/jsonata">GitHub</a><a class="github-button" href="https://github.com/jsonata-js/jsonata" data-icon="octicon-star" data-count-href="/jsonata-js/jsonata/stargazers" data-show-count="true" data-count-aria-label="# stargazers on GitHub" aria-label="Star this project on GitHub">Star</a></div></section><section class="copyright">Copyright © 2021 JSONata.org</section></footer></div></body></html>