23

Is there a function that reverses elements passed via pipeline?

E.g.:

PS C:\> 10, 20, 30 | Reverse 30 20 10 
1
  • As a pipleline only handles one object at a time you need to reverse the array before sending it to the pipe. Commented Dec 28, 2022 at 11:33

11 Answers 11

27

You can cast $input within the function directly to a array, and then reverse that:

function reverse { $arr = @($input) [array]::reverse($arr) $arr } 
Sign up to request clarification or add additional context in comments.

Comments

11
10, 20, 30 | Sort-Object -Descending {(++$script:i)} 

5 Comments

Hello, Please add some code explanation to help user to figure out easily
"script" is the scope of the "i" variable which is incremented each time it is evaluated: learn.microsoft.com/en-us/powershell/module/…
a shorter version would be: 10, 20, 30 | Sort-Object {(--$script:i)}
This only works if the input is sorted in ascending order
That is not reversing the original order...
8

Here's a remarkably compact solution:

function Reverse { [System.Collections.Stack]::new(@($input)) } 

Comments

5

One-liners inspired by this answer:

10,20,30 -as 'Collections.Stack' | Write-Verbose -vb 
[Collections.Stack](10,20,30) | Write-Verbose -vb 
10,20,30 | &{ @($Input) -as 'Collections.Stack' } | Write-Verbose -vb 
10,20,30 | &{ [Collections.Stack]@($Input) } | Write-Verbose -vb 

The first one looks the nicest, the second one is the shortest, and the last two are for performing the reversal mid-pipeline rather than before the pipeline.

Comments

3
$array = 10,20,30; (($array.Length - 1)..0) | %{ $array[$_] } 

Comments

2

Here's one approach:

function Reverse () { $arr = $input | ForEach-Object { $_ } [array]::Reverse($arr) return $arr } 

Comments

2

Using $input works for pipe, but not for parameter. Try this:

function Get-ReverseArray { Param( [Parameter(Mandatory = $true, Position = 0, ValueFromPipeLine = $true)] $Array ) begin{ $build = @() } process{ $build += @($Array) } end{ [array]::reverse($build) $build } } #set alias to use non-standard verb, not required.. just looks nicer New-Alias -Name Reverse-Array -Value Get-ReverseArray 

Test:

$a = "quick","brown","fox" #--- these all work $a | Reverse-Array Reverse-Array -Array $a Reverse-Array $a #--- Output for each fox brown quick 

Comments

1

I realize this doesn't use a pipe, but I found this easier if you just wanted to do this inline, there is a simple way. Just put your values into an array and call the existing Reverse function like this:

$list = 30,20,10 [array]::Reverse($list) # print the output. $list 

Put that in a PowerShell ISE window and run it the output will be 10, 20, 30.

Again, this is if you just want to do it inline. There is a function that will work for you.

Comments

1

You can use Linq.Enumerable.Reverse. Either of the following work:

,(10, 20, 30) | % { [Linq.Enumerable]::Reverse([int[]]$_) } ,([int[]]10, 20, 30) | % { [Linq.Enumerable]::Reverse($_) } 

The two challenges are putting the whole array into the pipeline rather than one element at a time (solved by making it an array of arrays with the initial comma) and hitting the type signature of Reverse (solved by the [int[]]).

Comments

0
10, 20, 30 | Sort-Object @{e={(++$script:i)};d=$true} 

same in full syntax:

10, 20, 30 | Sort-Object -Property @{Expression={(++$script:i)}; Descending=$true} 

$i shouldn't be local, so I use script scope modifier

() inside {} are needed to return the value of the calculation

Thus, each element acquires a "virtual property" with a serial number. By which it is sorted in reverse order.

Comments

-4

Try:

10, 20, 30 | Sort-Object -Descending 

1 Comment

This works if you also want to sort at the same time, but if you don't want to sort, this won't work. (E.g, maybe your original array was 20,10,30 and you want 30,10,20)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.