1

I have multiple arrays like this:

$arrayList1 = @()
$arrayList2 = @()

$arrayList1 += "james"
$arrayList1 += "henry"
$arrayList1 += "bob"

$arrayList2 += "scott"
$arrayList2 += "john"
$arrayList2 += "meera"
$arrayList2 += "lisa"
$arrayList2 += "joseph"

And i want to display the output like this:

arrayList1 arrayList2
james scott
henry john
bob meera
lisa
joseph

Here is what i tried:

$output = @{}
$output.add('arrayList1',$arrayList)
$output.add('arrayList2',$arrayLis2)
[PSCustomObject]$output

$output

And the output looks like this:

arrayList2 arrayList1
{scott,john,meera,lisa,joseph} {james,henry,bob}

Note: The array won't have same number of data.

Any suggestions how i can get it in the order i want it?

Thanks

Sanjeev

sanjeev
  • 765
  • 1
  • 7
  • 15
  • Does this answer your question? [Is there a PowerShell equivalent of \`paste\` (i.e., horizontal file concatenation)?](https://stackoverflow.com/questions/68070226/is-there-a-powershell-equivalent-of-paste-i-e-horizontal-file-concatenation) – iRon Jul 22 '21 at 15:32
  • `$arrayList1 |FullJoin $arrayList2` or use one of the do-it-yourself solutions and iterate through both arrays till they *both* empty. – iRon Jul 22 '21 at 15:35
  • @iRon this worked like charm until one of the arrayList didn't have any value. In that case looks like it doesn't display data correctly under right header. e.g. have 2 arrayList with data, have 3rd one without data, now use FullJoin and it removes the first arrayList header and only shows rest two. – sanjeev Jul 22 '21 at 17:12
  • @iRon done. https://github.com/iRon7/Join-Object/issues/28 – sanjeev Jul 22 '21 at 18:05
  • The issue is [explained and fixed](https://github.com/iRon7/Join-Object/issues/28#issuecomment-887397224) using: `$arrayList1 |FullJoin [object[]]$arrayList2` – iRon Jul 27 '21 at 11:54

2 Answers2

3

A concise solution (note: assumes that at least one of the arrays is non-empty):

$arrayList1 = 'james', 'henry', 'bob'
$arrayList2 = 'scott', 'john', 'meera', 'lisa', 'joseph'

foreach ($i in 0..([Math]::Max($arrayList1.Count, $arrayList2.Count)-1)) {
  [pscustomobject] @{ arrayList1 = $arrayList1[$i]; arrayList2 = $arrayList2[$i] }
}

The above yields the following, as desired:

arrayList1 arrayList2
---------- ----------
james      scott
henry      john
bob        meera
           lisa
           joseph

As an aside: The - ultimately rejected - proposal in GitHub issue #14732 suggested enhancing the foreach statement in a way that would have made parallel enumeration more convenient, along the lines of
foreach ($elemFromList1, $elemFromList2 in $arrayList1, $arrayList2) { ... }

mklement0
  • 382,024
  • 64
  • 607
  • 775
  • 2
    I guess I'm using `[math]::Max( )` instead of `Measure-Object -Maximum` from now on! – Santiago Squarzon Jul 22 '21 at 18:30
  • 2
    Makes sense, @SantiagoSquarzon. Avoiding the pipeline / cmdlets in expressions is generally preferable for performance reasons. – mklement0 Jul 22 '21 at 18:32
  • @mklement0 do you know if there is a way to sort that output of each arrayList? – sanjeev Jul 23 '21 at 12:23
  • Glad to hear it; @sanjeev, use [`Sort-Object`](https://learn.microsoft.com/powershell/module/microsoft.powershell.utility/sort-object); e.g.`$arrayList2 = 'scott', 'john', 'meera', 'lisa', 'joseph' | Sort-Object` or, after the fact `$arrayList2 = $arrayList2 | Sort-Object` – mklement0 Jul 23 '21 at 14:23
1

Try something like this:

$Boys = "Bob", "Noah", "Liam"
$Girls = "Olivia", "Sophia", "Charlotte", "Emma"

Function Fix-Arrays {
    Param(
        [Parameter(Mandatory=$True)]
        [string[]]$ArrayNames,
        [switch]$NoWarnings = $False
    )
    $ValidArrays,$ItemCounts = @(),@()
    $VariableLookup = @{}
    
    ForEach ($Array in $ArrayNames) {
        Try {
            $VariableData = Get-Variable -Name $Array -ErrorAction Stop
            $VariableLookup[$Array] = $VariableData.Value
            $ValidArrays += $Array
            $ItemCounts += ($VariableData.Value | Measure).Count
        }

        Catch {
            If (!$NoWarnings) {Write-Warning -Message "No variable found for [$Array]"}
        }
    }

    $MaxItemCount = ($ItemCounts | Measure -Maximum).Maximum
    $FinalArray = @()
    
    For ($Inc = 0; $Inc -lt $MaxItemCount; $Inc++) {
        $FinalObj = New-Object PsObject
        ForEach ($Item in $ValidArrays) {
            $FinalObj | Add-Member -MemberType NoteProperty -Name $Item -Value $VariableLookup[$Item][$Inc]
        }

        $FinalArray += $FinalObj
    }

    $FinalArray
}

Fix-Arrays -ArrayNames "Boys","Girls"

Just edit Fix-Arrays (line 41) and the top two example arrays to suit your needs.

  • updated question to show the actual way i am updating the arraylist. i tried this function and looks like it doesn't work for that. – sanjeev Jul 22 '21 at 18:32
  • **@sanjeev** That's odd, I used your modification and it worked for me. Is [this](https://pastebin.com/aRRD6DTj) how you formatted it? `Edit:` I updated the comments to better illustrate what I changed – Kanna Kujami Jul 22 '21 at 18:55
  • 1
    i think i know what i did wrong. i had it like this Fix-Arrays -ArrayNames $arrayList1, $arrayList2 when it should have been Fix-Arrays -ArrayNames "arrayList1", "arrayList2". Your solution is working as expected. thanks again – sanjeev Jul 22 '21 at 19:55