Combine-Array Powershell

  • By Lehbot
  • Fri 11 January 2019

This function combines each element of an array with everyone, even itself.

You can limit the columns to the count of elements in the initial array or specify the columns of the result.

If you have arrays in your array, then you have to do something else. This is meant for array containing single elements!

<#
.SYNOPSIS
This function combines each element of a given array to the same length as the count of the input array.

.DESCRIPTION
This function combines each element of a given array and outputs into a multi-dimensional array.
The amount of columns is the same as the count of the input Array.
Example:
$arrInput = @("Compute-S","Compute-M","Compute-L")
$output = Combine-Array -arrInitialInput $arrInput -Unique $true -MaxColumns 5

.NOTES
Only Arrays with single elements are valid. It is not intended to run with multi-dimensional array.

.COMPONENT
Nothing special here, i guess.

.LINK
Useful Link to ressources or others.

.Parameter arrInitialInput
A valid array containing single elements.

.Parameter arrInternalInput
Leave this blank. This parameter will be set by the recursive behavior of this script.

.Parameter iteration
Leave this blank. This parameter counts the iterations, that occured.

.Parameter Unique
Default value is $true. This parameter filters out double combinations after combining values and reordering those per row.
Example: (a,a),(a,b),(b,a),(b,b) -> (a,a),(a,b),(a,b),(b,b) -> (a,a),(a,b),(b,b)

.Parameter MaxColumns
If this value is bigger than 1 the result will be a maximal combination of each element with the columns specified by this parameter.

#>

#Initialization as an Arraylist to dynamically add elements.
[System.Collections.ArrayList]$arrOutput = @()
If($iteration -eq 0){
    #For the first run we need to set the $arrInternalInput to the initialInput.
    $arrInternalInput = $arrInitialInput
}
ForEach($row in $arrInternalInput){
    ForEach($col in $arrInitialInput){
        #If the element is not an array, we have to create one first. Powershell kills one element arrays to their specific value.
        If ($iteration -eq 0){
            [System.Collections.ArrayList]$temprow = [System.Collections.ArrayList]($row,$col)
        }
        Else{
            #We do not want to change the original row, because otherwise we get a longer array, than the input array. the count would get bigger. So a temporary object is needed.
            $tempRow = $row
            #Add an element to the actual row.
            $tempRow += $col
        }
        If ($Unique -eq $true){
            #Sorting of the arrays, which are the rows in out multidimenstional Array. Later we can sort again to filter for unique elements
            $tempRow = $tempRow | Sort-Object
        }
        #Insert the array as an element in an array
        $arrOutput+= (,$tempRow)
    }
}
#Filter double elements out in-between to speed up the process and spare out unnecessary combinations.
If ($Unique -eq $true){
    $arrOutput = $arrOutput | Sort-Object -Unique
}
$iteration++
#We need as much runs as elements -1 are in the initial array or specified by MaxColums if greater than 1. The -1 is necessary, because we already had one run.
If ($MaxColumns -le 1){
    $MaxColumns = $arrInitialInput.count
}
If ($iteration -lt $MaxColumns-1)
{
    #the actual output is the input for the next run, to make every combination possible.
    $arrOutput = Combine-Array -arrInitialInput $arrInitialInput -arrInternalInput $arrOutput -iteration $iteration -Unique $Unique -MaxColumns $MaxColumns
}
return $arrOutput

[System.Collections.ArrayList]$arrInput = @("Compute-S","Compute-M","Compute-L")
$output =$null
Measure-Command {$output = Combine-Array -arrInitialInput $arrInput -Unique $true -MaxColumns 10}