DataWeave Array Modules: Examples and Function Definitions

Shyam Raj Prasad
Another Integration Blog
8 min readNov 14, 2022

Arrays (dw::core::Arrays)

This module contains helper functions for working with arrays.

To use this module, you must import it to your DataWeave code. For you can add the line import * from dw::core::Arrays to the header of your DataWeave script. In this article, we will cover all the functions with examples and their internal functional definition.

countBy

Counts the elements in an array that returns true when the matching function is applied to the value of each element.

Example:

%dw 2.0
import * from dw::core::Arrays
output application/json
---
"countBy" : [1, 2, 3, 4] countBy (isEven($))

Output:

{
"countBy": 2
}

Function Definition:

fun countBy<T>(array: Array<T>, matchingFunction: (T) -> Boolean): Number =
(array reduce (item: T, carry: Number = 0) ->
if(matchingFunction(item))
carry + 1
else
carry) default 0

divideBy

Breaks up an array into sub-arrays that contain the specified number of elements.

Example:

%dw 2.0
import divideBy from dw::core::Arrays
output application/json
var arrays = [1,2,3,4]
---
arrays divideBy 2

Output:

[[1,2],[3,4]]

Function Definition:

fun divideBy<T>(items: Array<T>, amount: Number): Array<Array<T>> = do {
fun internalDivideBy<T>(items: Array<T>, amount: Number, carry: Array<T>, remaining: Number ): Array<Array<T>> =
items match {
case [x ~ xs] ->
if(remaining <= 1)
[carry << x ~ internalDivideBy(xs, amount, [], amount)]
else
internalDivideBy(xs, amount, carry << x , remaining - 1)
else ->
if(isEmpty(carry))
[]
else
[carry]
}
---
internalDivideBy(items, amount, [], amount)
}

drop

Drops the first n elements. It returns the original array when n <= 0 and an empty array when n > sizeOf(array).

Example:

%dw 2.0
import * from dw::core::Arrays
var users = ["Shyam", "Raj", "Prasad"]
output application/json
---
drop(users, 2)

Output:

[
"Prasad"
]

Function Definition:

fun drop<T>(array: Array<T>, n: Number): Array<T> = do {
if (n <= 0)
array
else
array[n to -1] default []
}

dropWhile

Drops elements from the array while the condition is met but stops the selection process when it reaches an element that fails to satisfy the condition.

Example:

%dw 2.0
import * from dw::core::Arrays
output application/json
var arr = [0,1,3,2,1]
---
arr dropWhile $ < 3

Output:

[
3,
2,
1
]

Function Definition:

fun dropWhile<T>(array: Array<T>, condition: (item: T) -> Boolean): Array<T> = do {
array match {
case [] -> array
case [head ~ tail] ->
if (condition(head))
dropWhile(tail, condition)
else
array
}
}

every

Returns true if every element in the array matches the condition.

Example:

%dw 2.0
import * from dw::core::Arrays
output application/json
---
[1,2,3] every ($ == 1)

Output:

false

Function Definition:

fun every<T>(list: Array<T>, condition: (T) -> Boolean): Boolean = do {
@TailRec
fun internalEvery<T>(list: Array<T>, condition: (T) -> Boolean): Boolean =
list match {
case [] -> true
case [head ~ tail] ->
if(condition(head))
internalEvery(tail, condition)
else
false
}
---
internalEvery(list, condition)

firstWith

Returns the first element that satisfies the condition, or returns null if no element meets the condition.

Example:

%dw 2.0
output application/json
import firstWith from dw::core::Arrays
var users = [
{ name: "Shyam", lastName: "Prasad" },
{ name: "Raj", lastName: "Prasad" },
{ name: "Shyam", lastName: "Raj" }
]
---
users firstWith ($.name == "Shyam")

Output:

{
"name": "Shyam",
"lastName": "Prasad"
}

Function Definition:

fun firstWith<T>(array:Array<T>, condition: (item: T, index: Number) ->  Boolean): T | Null = do {
filter(array, condition)[0]
}

indexOf

Returns the index of the first occurrence of an element within the array. If the value is not found, the function returns -1.

Example:

%dw 2.0
import * from dw::core::Arrays
output application/json
var users = ["Shyam", "Raj", "Prasad"]
---
indexOf(users, "Raj")

Output:

1

Function Definition:

fun indexOf(array: Array, value: Any): Number =
find(array, value)[0] default -1

indexWhere

Returns the index of the first occurrence of an element that matches a condition within the array. If no element matches the condition, the function returns -1.

Example:

%dw 2.0
import * from dw::core::Arrays
output application/json
var users = ["Shyam", "Raj", "Prasad"]
---
users indexWhere (item) -> item startsWith "Pra"

Output:

2

Function Definition:

fun indexWhere<T>(array: Array<T>, condition: (item: T) -> Boolean): Number = do {
fun private_indexWhere(arr: Array<T>, currIndex: Number) = do {
arr match {
case [] -> -1
case [head ~ tail] ->
if (condition(head))
currIndex
else
private_indexWhere(tail, currIndex+1)
}
}
---
private_indexWhere(array, 0)
}

join

Joins two arrays of objects by given ID criteria.

Example:

%dw 2.0
import * from dw::core::Arrays
var users = [
{ id: "1", name: "Shyam"
},
{ id: "2", name: "Raj"
},
{ id: "3", name: "Prasad"
},
{ id: "5", name: "Pawan"
}
]
var products = [
{ ownerId: "1", name: "DataWeave"
},
{ ownerId: "1", name: "Java"
},
{ ownerId: "3", name: "Python"
},
{ ownerId: "4", name: "React"
}
]
output application/json
---
join(users, products, (user) -> user.id, (product) -> product.ownerId)

Output:

[
{
"l": {
"id": "1",
"name": "Shyam"
},
"r": {
"ownerId": "1",
"name": "DataWeave"
}
},
{
"l": {
"id": "1",
"name": "Shyam"
},
"r": {
"ownerId": "1",
"name": "Java"
}
},
{
"l": {
"id": "3",
"name": "Prasad"
},
"r": {
"ownerId": "3",
"name": "Python"
}
}
]

Function Definition:

fun join<L <: {}, R <: {}>(left:Array<L>, right:Array<R>, leftCriteria: (leftValue: L) -> String, rightCriteria: (rightValue: R) -> String): Array<Pair<L, R>> = do {
var groupedBy = right groupBy ((r) -> rightCriteria(r))
---
left flatMap ((lValue, index) -> do {
var leftValue = leftCriteria(lValue) as String
var value = groupedBy[leftValue] default []
---
value map ((rValue, index) ->
{l: lValue, r: rValue}
)
})
}

leftJoin

Joins two arrays of objects by given ID criteria.

Example:

%dw 2.0
import * from dw::core::Arrays
var users = [
{ id: "1", name: "Shyam"
},
{ id: "2", name: "Raj"
},
{ id: "3", name: "Prasad"
},
{ id: "5", name: "Pawan"
}
]
var products = [
{ ownerId: "1", name: "DataWeave"
},
{ ownerId: "1", name: "Java"
},
{ ownerId: "3", name: "Python"
},
{ ownerId: "4", name: "React"
}
]
output application/json
---
leftJoin(users, products, (user) -> user.id, (product) -> product.ownerId)

Output:

[
{
"l": {
"id": "1",
"name": "Shyam"
},
"r": {
"ownerId": "1",
"name": "DataWeave"
}
},
{
"l": {
"id": "1",
"name": "Shyam"
},
"r": {
"ownerId": "1",
"name": "Java"
}
},
{
"l": {
"id": "2",
"name": "Raj"
}
},
{
"l": {
"id": "3",
"name": "Prasad"
},
"r": {
"ownerId": "3",
"name": "Python"
}
},
{
"l": {
"id": "5",
"name": "Pawan"
}
}
]

Function Definition:

fun leftJoin<L <: {}, R <: {}>(left:Array<L>, right:Array<R>, leftCriteria: (leftValue: L) -> String, rightCriteria: (rightValue: R) -> String): Array<{l: L,r?: R}> = do {
var groupedBy = right groupBy ((r) -> rightCriteria(r))
---
left flatMap ((lValue, index) -> do {
var leftValue = leftCriteria(lValue) as String
var value = groupedBy[leftValue] default []
---
value match {
case [] -> [{l:lValue}]
else ->
value map ((rValue, index) ->
{l:lValue , r:rValue}
)
}
})
}

outerJoin

Joins two arrays of objects by a given ID criteria.

Example:

%dw 2.0
import * from dw::core::Arrays
var users = [
{ id: "1", name: "Shyam"
},
{ id: "2", name: "Raj"
},
{ id: "3", name: "Prasad"
},
{ id: "5", name: "Pawan"
}
]
var products = [
{ ownerId: "1", name: "DataWeave"
},
{ ownerId: "1", name: "Java"
},
{ ownerId: "3", name: "Python"
},
{ ownerId: "4", name: "React"
}
]
output application/json
---
outerJoin(users, products, (user) -> user.id, (product) -> product.ownerId)

Output:

[
{
"l": {
"id": "1",
"name": "Shyam"
},
"r": {
"ownerId": "1",
"name": "DataWeave"
}
},
{
"l": {
"id": "1",
"name": "Shyam"
},
"r": {
"ownerId": "1",
"name": "Java"
}
},
{
"l": {
"id": "2",
"name": "Raj"
}
},
{
"l": {
"id": "3",
"name": "Prasad"
},
"r": {
"ownerId": "3",
"name": "Python"
}
},
{
"l": {
"id": "5",
"name": "Pawan"
}
},
{
"r": {
"ownerId": "4",
"name": "React"
}
}
]

Function Definition:

fun outerJoin<L <: {}, R <: {}>(left:Array<L>, right:Array<R>, leftCriteria: (leftValue: L) -> String, rightCriteria: (rightValue: R) -> String): Array<{l?: L,r?: R}> = do {
var leftGroupBy = left groupBy (r) -> leftCriteria(r)
---
leftJoin(left,right,leftCriteria,rightCriteria) ++ do {
right
filter ((rValue, index) -> !leftGroupBy[rightCriteria(rValue) as String]?)
map ((rightValue) ->
{
r: rightValue
}
)
}
}

partition

Separates the array into the elements that satisfy the condition from those that do not.

Example:

%dw 2.0
import * from dw::core::Arrays
output application/json
var arr = [0,1,2,3,4,5]
---
arr partition (item) -> isEven(item)

Output:

{
"success": [
0,
2,
4
],
"failure": [
1,
3,
5
]
}

Function Definition:

fun partition<T>(array: Array<T>, condition: (item: T) -> Boolean): {success: Array<T>, failure: Array<T>} = {
success: array filter (item) -> condition(item),
failure: array filter (item) -> !condition(item)
}

slice

Selects the interval of elements that satisfy the condition: from <= indexOf(array) < until .

Example:

%dw 2.0
import * from dw::core::Arrays
output application/json
var arr = [0,1,2,3,4,5]
---
slice(arr, 1, 4)

Output:

[
1,
2,
3
]

Function Definition:

fun slice<T>(array: Array<T>, from: Number, until: Number): Array<T> = do {
if (from < 0)
slice(array, 0, until)
else if (from >= until)
[]
else
array[from to (until-1)] default array[from to -1] default []
}

some

Returns true if at least one element in the array matches the specified condition.

Example:

%dw 2.0
import * from dw::core::Arrays
output application/json
---
[1,2,3] some (($ mod 2) == 0)

Output:

true

Function Definition:

fun some<T>(list: Array<T>, condition: (T) -> Boolean): Boolean = do {
@TailRec
fun internalSome<T>(list: Array<T>, condition: (T) -> Boolean) =
list match {
case [] -> false
case [head ~ tail] ->
if(condition(head))
true
else
internalSome(tail, condition)
}
---
internalSome(list, condition)
}

splitAt

Splits an array into two at a given position.

Example:

%dw 2.0
import * from dw::core::Arrays
output application/json
var users = ["Shyam", "Raj", "Prasad"]
---
users splitAt 1

Output:

{
"l": [
"Shyam"
],
"r": [
"Raj",
"Prasad"
]
}

Function Definition:

fun splitAt<T>(array: Array<T>, n: Number): Pair<Array<T>, Array<T>> = {
l: array take n,
r: array drop n
}

splitWhere

Splits an array into two at the first position where the condition is met.

Example:

%dw 2.0
import * from dw::core::Arrays
output application/json
var users = ["Shyam", "Raj", "Prasad", "Shyam"]
---
users splitWhere (item) -> item startsWith "Pra"

Output:

{
"l": [
"Shyam",
"Raj"
],
"r": [
"Prasad",
"Shyam"
]
}

Function Definition:

fun splitWhere<T>(array: Array<T>, condition: (item: T) -> Boolean): Pair<Array<T>, Array<T>> = do {
var index = array indexWhere (item) -> condition(item)
---
array splitAt index
}

sumBy

Returns the sum of the values of the elements in an array.

Example:

%dw 2.0
import * from dw::core::Arrays
output application/json
---
[{ a: 1 }, { a: 2 }, { a: 3 } ] sumBy $.a

Output:

6

Function Definition:

fun sumBy<T>(array: Array<T>, numberSelector: (T) -> Number): Number =
(array reduce (item: T, carry: Number = 0) ->
numberSelector(item) + carry) default 0

take

Selects the first n elements. It returns an empty array when n <= 0 and the original array when n > sizeOf(array).

Example:

%dw 2.0
import * from dw::core::Arrays
var users = ["Shyam", "Raj", "Prasad"]
output application/json
---
take(users, 2)

Output:

[
"Shyam",
"Raj"
]

Function Definition:

fun take<T>(array: Array<T>, n: Number): Array<T> = do {
if (n <= 0)
[]
else
array[0 to (n-1)] default array
}

takeWhile

Selects elements from the array while the condition is met but stops the selection process when it reaches an element that fails to satisfy the condition.

Example:

%dw 2.0
import * from dw::core::Arrays
output application/json
var arr = [0,1,2,1]
---
arr takeWhile $ <= 1

Output:

[
0,
1
]

Function Definition:

fun takeWhile<T>(array: Array<T>, condition: (item: T) -> Boolean): Array<T> = do {
array match {
case [] -> array
case [head ~ tail] ->
if (condition(head))
[head ~ takeWhile(tail, condition)]
else
[]
}
}

References: https://docs.mulesoft.com/dataweave/2.4/dw-arrays

GitHub Repo: https://github.com/shyamrajprasad/dataweave-fun/tree/master/src/main/dw/core/arrays

--

--

Shyam Raj Prasad
Another Integration Blog

Engineering Leader at Tricon Infotech Private Limited | Mulesoft Certified Developer and Architect