Azure Bicep lambda expressions

If you have a C# (or almost any other language) development background, this will be familiar to you. Recently, the Bicep team introduced lambda expressions. With the introduction of lambda expressions in Azure Bicep, you can manipulate arrays. In Bicep, the operator declaration is =>. The new functions that support lambda’s and are implemented:

  • filter()
  • map()
  • reduce()
  • sort()

The lambda expression format is as follows:

<lambda variable> => <expression>

To use Azure Bicep lambdas, the version requirement is v0.10.61 or higher.

Bicep Example

To illustrate how these lambda expressions work, I created an example array in Bicep. In this Bicep file, an array has been declared as a variable with information about groceries:

var varGroceryStore = [
{
productName: 'Icecream'
productPrice: 5
productCharacteristics: [
'Vegan'
'Seasonal'
]
}
{
productName: 'Cheese'
productPrice: 2
productCharacteristics: [
'Bio'
]
}
{
productName: 'Banana'
productPrice: 4
productCharacteristics: [
'Bio'
]
}
]

If you want to run the examples from the blog post, you can run the following command:

az deployment group create --resource-group <rg> --template-file <file> --query "properties.outputs"

filter()

Let’s take a looks at the first function: filter(). The filter function filters an array based on a given criteria. For example, only show the products priced higher than 4 or where the characteristics of the product contain a specific condition.

The filter method expects two parameters, namely: filter(inputArray, lambda expression). The first parameter is the array that has to be filtered, and the second parameter is the lambda expression that is applied to each input array element.

Let’s see filter in action:

Filter every object that has a lower productPrice than 4:

output outUsingFilter array = filter(varGroceryStore, item => item.productPrice >= 4)
view raw filter1.bicep hosted with ❤ by GitHub

Result:

{
"outUsingFilter": {
"type": "Array",
"value": [
{
"productCharacteristics": [
"Vegan",
"Seasonal"
],
"productName": "Icecream",
"productPrice": 5
},
{
"productCharacteristics": [
"Bio"
],
"productName": "Banana",
"productPrice": 4
}
]
}
}

Filter every object that does not have the characteristic ‘Bio’:

output outUsingFilterAndContains array = filter(varGroceryStore, item => contains(item.productCharacteristics, 'Bio'))
view raw filter2.bicep hosted with ❤ by GitHub

Result:

{
"outUsingFilterAndContains": {
"type": "Array",
"value": [
{
"productCharacteristics": [
"Bio"
],
"productName": "Cheese",
"productPrice": 2
},
{
"productCharacteristics": [
"Bio"
],
"productName": "Banana",
"productPrice": 4
}
]
}
}

map()

The map() function applies a function to the element selected from the array. 

The map function expects two parameters, namely: map(inputArray, lamba expression).

In the example, there is an array containing multiple objects, which represent a product in the grocery store. If you only want to use the productName you can use map() to select the property productName and set this as an output or variable:

output outUsingMap array = map(varGroceryStore, item => item.productName)
view raw map1.bicep hosted with ❤ by GitHub

Result

{
"outUsingMap": {
"type": "Array",
"value": [
"Icecream",
"Cheese",
"Banana"
]
}
}

Use map and create a sentence with string interpolation:

output outUsingMapAndStringInterpolation array = map(varGroceryStore, item => 'The price of item ${item.productName} is ${item.productPrice}.')
view raw map2.bicep hosted with ❤ by GitHub

Result

{
"outUsingMapAndStringInterpolation": {
"type": "Array",
"value": [
"The price of item Icecream is 5.",
"The price of item Cheese is 2.",
"The price of item Banana is 4."
]
}
}

Use map and create an object and added productNumber and discountedPrice:

output outputDiscount array = map(range(0, length(varGroceryStore)), item => {
productNumber: item
productName: varGroceryStore[item].productName
discountedPrice: 'The item ${varGroceryStore[item].productName} is on sale. Sale price: ${(varGroceryStore[item].productPrice / 2)}'
})
view raw map3.bicep hosted with ❤ by GitHub

Result

{
"outputDiscount": {
"type": "Array",
"value": [
{
"discountedPrice": "The item Icecream is on sale. Sale price: 2",
"productName": "Icecream",
"productNumber": 0
},
{
"discountedPrice": "The item Cheese is on sale. Sale price: 1",
"productName": "Cheese",
"productNumber": 1
},
{
"discountedPrice": "The item Banana is on sale. Sale price: 2",
"productName": "Banana",
"productNumber": 2
}
]
}
}

The non-lambda way

It’s possible to achieve the same using foreach loops, but when you want to create an object, it will be easier to use map. The foreach loop would look like this:

var varGetProductNameUsingLoop = [for item in varGroceryStore: item.productName]

reduce()

The reduce() function can be seen as an accumulator. With reduce() you can generate a single value from properties in an array. In the given example, you can use the productPrice to calculate the total price of every product in the grocery store.

The reduce function expects three parameters, namely: reduce(inputArray, initialValue, lamba expression).

Let’s see reduce() in action.

Use reduce to accumulate product prices:

var varReceipt = map(varGroceryStore, items => items.productPrice)
output outUsingReduce int = reduce(varReceipt, 0, (currentValue, previousValue) => currentValue + previousValue)
view raw reduce1.bicep hosted with ❤ by GitHub

First, use map() to get the productPrice, after that use reduce() to accumulate the productPrice values. The 0 means the starting value to accumulate from. The reduce function loops through the values and accumulates the currentValue and previousValue:

  • First loop: currentValue (5) + previousValue (0)
  • Second loop: currentValue (2) + previousValue (5)
  • Third Loop and last loop: currentValue (4) + previousValue (7)
  • Outcome: 11

Result

{
"outUsingReduce": {
"type": "Int",
"value": 11
}
}

sort()

The sort() function sorts an array based on a given criteria. In the given example, the array of groceries can be sorted using the productPrice from low to high or productNames can be sorted alphabetically. The sort function expects two parameters, namely: sort(inputArray, lamba expression).

Let’s see sort() in action.

Sort the array with the productPrices from low to high:

output outUsingSort array = sort(varGroceryStore, (a, b) => a.productPrice <= b.productPrice)
view raw sort1.bicep hosted with ❤ by GitHub

Result

{
"outUsingSort": {
"type": "Array",
"value": [
{
"productCharacteristics": [
"Bio"
],
"productName": "Cheese",
"productPrice": 2
},
{
"productCharacteristics": [
"Bio"
],
"productName": "Banana",
"productPrice": 4
},
{
"productCharacteristics": [
"Vegan",
"Seasonal"
],
"productName": "Icecream",
"productPrice": 5
}
]
}
}

Sort the productNames alphabetically:

output outUsingSort array = sort(varGroceryStore, (a, b) => a.productName <= b.productName)
view raw sort2.bicep hosted with ❤ by GitHub

Result

{
"outUsingSort": {
"type": "Array",
"value": [
{
"productCharacteristics": [
"Bio"
],
"productName": "Banana",
"productPrice": 4
},
{
"productCharacteristics": [
"Bio"
],
"productName": "Cheese",
"productPrice": 2
},
{
"productCharacteristics": [
"Vegan",
"Seasonal"
],
"productName": "Icecream",
"productPrice": 5
}
]
}
}

Conclusion

This is how lambda’s can be used in Azure Bicep. I think lambda’s are a great addition to the Azure Bicep function suite because of the ability to manipulate an array and use these manipulations in outputs or variables.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s