Powershell\'s array notation has rather bizarre, albeit documented, behavior for slicing the end of arrays. This section from the official documentation sums up the bizarreness
I believe this is the right way to do it. all other methods require more code.
$a[1..($a.Count-1)]
Also, if array is converted to string it becomes easy to get data as below:
$a = 0,1,2,3
[string]::Concat($a).Substring(1)
This could be the most idiomatic way to slice an array with both of its ends:
$array[start..stop] where stop is defined by taking the length of the array minus a value to offset from the end of the array:
$a = 1,2,3,4,5,6,7,8,9
$start = 2
$stop = $a.Length-3
$a[$start..$stop]
This will return 3 4 5 6 7
The start value starts counting with zero, so a start value of '2' gives you the third element of the array. The stop value is calculated with ($a.Length-3), this will drop the last two values because $a.Length-3 itself is included in the slice.
I have defined $start and $stop for clarity, obviously you can also write it like this:
$a = 1,2,3,4,5,6,7,8,9
$a[2..($a.Length-3)]
This will also return 3 4 5 6 7
$arr = @(10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
$arr | Select-Object -First 5 | Select-Object -Index (@(0..4) | Where-Object { $_ % 2 -eq 0})
$arr | Select-Object -Last 5
$arr | Select-Object -Unique
$arr | Sort-Object | Select-Object -Unique
$arr | Where-Object { $_ % 5 -eq 0 } | Sort-Object | Select-Object -Unique
$arr | Select-Object -First ($arr.Count - 3)
Actually code speaks for itself. I event don't need to explain.
However, 1) Provide the first five elements, but each second of those five. Equal to arr[:5:2] in Python 2) Get the last five elements. 3) Gives unique elements 4) Firstly sort and then provide unique 5) Gives only elements which equal 0 by applying modulo of 5, sort, unique. 5) Provide the first count of elements in that array minus three elements only.
If you want to get n elements from the end of an array simply fetch the elements from -n to -1:
PS C:\> $a = 0,1,2,3 PS C:\> $n = 2 PS C:\> $a[-$n..-1] 2 3
Edit: PowerShell doesn't support indexing relative to both beginning and end of the array, because of the way $a[$i..$j]
works. In a Python expression a[i:j]
you specify i
and j
as the first and last index respectively. However, in a PowerShell ..
is the range operator, which generates a sequence of numbers. In an expression $a[$i..$j]
the interpreter first evaluates $i..$j
to a list of integers, and then the list is used to retrieve the array elements on these indexes:
PS C:\> $a = 0,1,2,3 PS C:\> $i = 1; $j = -1 PS C:\> $index = $i..$j PS C:\> $index 1 0 -1 PS C:\> $a[$index] 1 0 3
If you need to emulate Python's behavior, you must use a subexpression:
PS C:\> $a = 0,1,2,3 PS C:\> $i = 1; $j = -1 PS C:\> $a[$i..($a.Length+$j-1)] 1 2
Combine Select-Object -Skip
and Select-Object -SkipLast
like:
$a = 0,1,2,3
$a | Select-Object -Skip 1 | Select-Object -SkipLast 1
Returns:
1
2
Not as elegant as Python, but at least you don't have to use Count
or Length
, meaning this also works if the array isn't stored in a variable.
If you are looking for, say, the first three and last three elements in an array, with the results in an array, a little array addition will take care of the need.
[array]$A = (([int][char]'A')..([int][char]'Z')) | ForEach-Object {[char]$_}
$B = $A[0..2]+$A[-3..-1]
Clear-Host
Write-Host "Original List"
Write-Host $A -NoNewline -Separator ', '
Write-Host
Write-Host "First three and last three"
Write-Host $B -NoNewline -Separator ', '
Yields:
Original List
A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z
First three and last three
A, B, C, X, Y, Z