Indexing arrays from the end #10104
Labels
design approved
The team has reviewed and signed off on this design
enhancement
New feature or request
good first issue
Good for newcomers
proposal
Milestone
Array elements in ARM can only be accessed by supplying the zero-based index as a property accessor. When a user wants to access an element by its position relative to the end of the array, there are two options:
length(<array>) - <offset from end>
, orlast
function.These approaches cannot be used in all cases. The first construct dereferences the array in two separate locations and is therefore only compatible with named values. The second construct can only access a specific index and is somewhat misleadingly named; it is the equivalent of C#'s
.LastOrDefault()
method rather than C#'s.Last()
method (in that it will returnnull
rather than raise an error when called on an empty collection).For accessing arbitrary offsets from the end of anonymous values, a separate approach is needed.
Proposal
Bicep should add a new operator to access an array element by its position relative to the end of the array. Following C#'s example, I suggest that we use a circumflex (
^
) character that follows the opening square bracket and precedes the index expression. For example:This operator should be combinable with the safe dereference operator:
In ARM, this operator would be represented by two fuctions:
indexFromEnd
(corresponding to[^<index>]
) andtryIndexFromEnd
(corresponding to[?^<index>]
). Both functions would take exactly two parameters:For the second parameter, only natural numbers would be accepted. This value would be translated into a normal, zero-based array index by subtracting the provided value from the length of the collection. I.e., given an array with five elements,
indexFromEnd(<array>, 2)
would be equivalent to<array>[length(<array>) - 2]
(or simply<array>[3]
).If the resolved zero-based index is negative,
indexFromEnd
would raise an error, whereastryIndexFromEnd
would returnnull
.tryIndexFromEnd
should also returnnull
if the first parameter is not an array (to match the behavior oftryGet(<not an array>, 0)
), whereas this would raise an error inindexFromEnd
.Alternatives considered
Support negative indicies in ARM and Bicep
While an attractively simple proposal, supporting negative indices directly in ARM (i.e.,
<array>[-1]
to get the last element of an array) could make some expressions that would previously have raised an error instead return an unexpected value.indexOf
andlastIndexOf
use-1
as a sentinel value meaning that the sought element was not found in the provided collection; it would be odd if<array>[indexOf(<arrayToSearch>, <element>)]
simply returned the last element of the array should<element>
not be found in<arrayToSearch>
.The text was updated successfully, but these errors were encountered: