# What's new in 4.0/Operator::@

(new to 4.0)

The 'position' of value x in an index i is the number between 1 and n (=Size(i)) for which Slice(i, n) = x. The position operator "@" returns the numeric position of elements in an index. The first element of an index is at position 1, the last element of an index is at position Size(i), etc.

You can use "@" in three ways:

@i → an array of integers from 1 to Size(i) indexed by i.
@[i = x] → the position of value x in index i -- or NULL if x is not an element of i
e[@i = n] -→ the nth Slice of expression e over index i.

## Examples

We'll use the following indexes for illustration:

 Index Car_type := ['VW', 'Honda', 'BMW']
Index Time := [0, 1, 2, 3, 4]
Index Years := Time + 2007

@CarType →
Car_Type ▶
'VW' 'Honda' 'BMW'
1 2 3
@[Car_type = 'Honda'] → 2
Car_type[@Car_type = 2] → 'Honda'
@Time →
Time ▶
0 1 2 3 4
1 2 3 4 5
@[Time = 2] → 3
Time[@Time = 3] → 2
(Time + 2007)[@Time = 3] → 2009

You can use the slice variation to re-index an array by another array having the same length but different elements. Suppose Revenue is indexed by Time, then this returns the same array indexed by Years:

Revenue[@Year = @Time]

## Notes

@I is equivalent to Cumulate(1, I)

If an index has duplicate elements, then subscripting (associative indexing) is ambiguous. For example,

Index In1 := ['a', 'b', 'a', 'c']
Index In2 := ['a', 'b', 'a', 'c']
Variable A := Array(In1, [7, 3, 5, 9])

If you were to re-index using A[In1 = In2], you would obtain:

A[In1 = In2] →
In2 ▶
'a' 'b' 'a' 'c'
7 4 7 9

Since A[In1='a'] returns 7. Because of the duplicate in the index values, an array value was lost. When duplicates are possible, accessing elements by position removes the ambiguity:

A[@In1 = @In2] →
In2 ▶
'a' 'b' 'a' 'c'
7 4 5 9

In variable definitions, it is more often the case that associative access (subscripting, non-positional) is preferred. Associative access is more robust when elements are added to indexes. For example, Revenue[Region='Europe'] doesn't break when a new region is inserted, while Revenue[@Region = 5] would change. However, in User-Defined Functions, positional indexing (i.e., is of the @ operator) is often more robust than associative indexing. For example, when a function uses two equal-length indexes (e.g., for a square matrix), with positional indexing the expression does not have to assume the indexes have identical elements or no duplicate elements.