Hanna Morgen
Hanna Morgen

Reputation: 7

How should I output my result of sorting in console for each sort steps and could be controlled by Verbose parameter

My bubble sort algorithm in Powershell. I will be appreciated if you help me to output in console for each sort steps and could be controlled by Verbose parameter. Thank you in advanced;):

  function bubble_sort($a){
     $n=$a.Length
     for($i=1; $i -le ($n-1); $i+=1)
     {
         for($j=0; $j -le ($n-$i-1); $j+=1)
         {
             if($a[$j] -le $a[$j+1])
             {
                 $temp=$a[$j]
                 $a[$j]=$a[$j+1]
                 $a[$j+1]=$temp
             }
         }
     }
     return $a
     }
     
     $a=@()
     $a=@(10,50,40,20,70,60,30)
     $sorted=bubble_sort $a
     Write-Host Sorted Array:
     foreach($s in $sorted){
     $s
     }

Upvotes: 0

Views: 698

Answers (1)

Theo
Theo

Reputation: 61013

To create a function that can output Verbose messages, you need to add [CmdletBinding()] and a param(..) block to it, so it becomes an Advanced function.

I would recommend using a parameter name that describes the meaning better, so $Array instead of $a and rename the function to comply with the PowerShell Verb-Noun naming convention.

The function could also be more versatile if you add a switch parameter with wich you can use it to sort in Ascending or Descending order.

Below a rewrite of your bubble sorting function:

function Sort-Bubble {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true, Position = 0)]
        [array]$Array,

        [switch]$Descending
    )   
    $n = $Array.Count
    $order = if ($Descending) { 'Descending' } else { 'Ascending' }
    Write-Verbose "Start sorting $n elements in $order order"
    for($i = 1; $i -lt $n; $i++) {
        for($j = 0; $j -lt ($n - $i); $j++) {
            Write-Verbose "Comparing value $($Array[$j]) against value $($Array[$j + 1])"
            if ($Descending) {
                if ($Array[$j] -lt $Array[$j+1]) {
                    Write-Verbose "Swapping values$($Array[$j]) <--> $($Array[$j + 1])"
                    # in PowerShel, you can swap like this:
                    $Array[$j], $Array[$j + 1] = $Array[$j + 1], $Array[$j]
                    # so you don't need a $temp variable
                    # $temp = $Array[$j]
                    # $Array[$j] = $Array[$j + 1]
                    # $Array[$j + 1] = $temp
                }
            }
            else {
                # default Ascending sort order
                if ($Array[$j] -gt $Array[$j + 1]) {
                    Write-Verbose "Swapping values $($Array[$j]) <--> $($Array[$j + 1])"
                    $Array[$j], $Array[$j + 1] = $Array[$j + 1], $Array[$j]
                }                
            }
        }
    }
    # the comma embeds the array in a 1-element array
    # this prevents that arrays with just one item get 'unrolled' by
    # PowerShell and makes sure the returned value is an array.
    return ,$Array  
}

Use it for Ascending sort:

$a = 10,50,40,20,70,60,30
$sorted = Sort-Bubble $a -Verbose
Write-Host Sorted Array:
$sorted

or Descending:

$a = 10,50,40,20,70,60,30
$sorted = Sort-Bubble $a -Descending -Verbose
Write-Host Sorted Array:
$sorted

Some tips:

  • To define an array, you don't need to embed it in @(). Just a series of comma separated values suffice
  • To return an array from a function, prepend a single (unary) comma to the output. When an array only has one element, PowerShell will 'unroll' it and returns a scalar. If you want the function to always return an array, the unary comma wraps that inside another single-element array. That one gets unrolled, leaving the original array returned.
  • To swap values, PowerShell lets you do $a, $b = $b, $a so you don't have to use a third temporary variable

Upvotes: 1

Related Questions