在powershell中将两个数组对象合并为一个数组对象[duplicate]

nuypyhwy  于 2023-02-19  发布在  Shell
关注(0)|答案(1)|浏览(243)
    • 此问题在此处已有答案**:

In PowerShell, what's the best way to join two tables into one?(5个答案)
15天前关闭。
如何在PowerShell中将两个数组对象合并为一个数组对象?
阵列A

| Date  | AAA |
| 2023-01-01 | 1 |
| 2023-01-02 | 2 |
| 2023-01-03 | 3 |
| 2023-01-04 | 4 |
| 2023-01-05 | 5 |
| 2023-01-06 | 6 |
| 2023-01-07 | 7 |
| 2023-01-08 | 8 |
| 2023-01-09 | 9 |
| 2023-01-10 | 10 |

阵列B

| D_Date  | BBB |
| 2023-01-06 | 6 |
| 2023-01-07 | 7 |
| 2023-01-08 | 8 |
| 2023-01-09 | 9 |
| 2023-01-10 | 10 |

结果

| Date  | AAA | BBB |
| 2023-01-01 | 1 | |
| 2023-01-02 | 2 | |
| 2023-01-03 | 3 | |
| 2023-01-04 | 4 | |
| 2023-01-05 | 5 | | 
| 2023-01-06 | 6 | 6 |
| 2023-01-07 | 7 | 7 |
| 2023-01-08 | 8 | 8 |
| 2023-01-09 | 9 | 9 |
| 2023-01-10 | 10 | 10 |

下面是我的代码示例。

$listA = [pscustomobject]@(
    [pscustomobject]@{
        Date = Get-Date "2023-01-01"
        AAA = "1"
    }, [pscustomobject]@{
        Date = Get-Date "2023-01-02"
        AAA = "2"
    }, [pscustomobject]@{
        Date = Get-Date "2023-01-03"
        AAA = "3"
    }, [pscustomobject]@{
        Date = Get-Date "2023-01-04"
        AAA = "4"
    }, [pscustomobject]@{
        Date = Get-Date "2023-01-05"
        AAA = "5"
    }, [pscustomobject]@{
        Date = Get-Date "2023-01-06"
        AAA = "6"
    }, [pscustomobject]@{
        Date = Get-Date "2023-01-07"
        AAA = "7"
    }, [pscustomobject]@{
        Date = Get-Date "2023-01-08"
        AAA = "8"
    }, [pscustomobject]@{
        Date = Get-Date "2023-01-09"
        AAA = "9"
    }, [pscustomobject]@{
        Date = Get-Date "2023-01-10"
        AAA = "10"
    }
)

$listB = [pscustomobject]@(
    [pscustomobject]@{
        D_Date = Get-Date "2023-01-06"
        BBB = "6"
    }, [pscustomobject]@{
        D_Date = Get-Date "2023-01-07"
        BBB = "7"
    }, [pscustomobject]@{
        D_Date = Get-Date "2023-01-08"
        BBB = "8"
    }, [pscustomobject]@{
        D_Date = Get-Date "2023-01-09"
        BBB = "9"
    }, [pscustomobject]@{
        D_Date = Get-Date "2023-01-10"
        BBB = "10"
    }
)

foreach ($objA in $listA) {
    $objB = $listB | ? { $_.D_Date -eq $objA.Date }
    $objA | Add-Member -Name "BBB" -Type NoteProperty -Value $objB.BBB
}

我尝试循环列表A,并从列表B中为属性BBB赋值,但对于大数组(4000 - 5000个对象)来说似乎非常慢,如果列表B的结果比列表A多,我的代码将无法工作,但我需要使用属性"日期"而不是"D_日期"。
我怎样才能提高性能和处理这种情况?

cunj1qz1

cunj1qz11#

使用Group-Object可能会提高代码的性能,下面将按两个数组的Date/D_Date属性对它们进行分组,然后枚举每个组以构造新的合并对象:

$listA + $listB | Group-Object { if($value = $_.Date) { return $value }; $_.D_Date } |
    ForEach-Object {
        [pscustomobject]@{
            Date = $_.Name
            AAA  = $_.Group.AAA | Select-Object -First 1
            BBB  = $_.Group.BBB | Select-Object -First 1
        }
    }

这样做的结果会像您预期的结果一样:

Date                  AAA BBB
----                  --- ---
1/1/2023 12:00:00 AM  1
1/2/2023 12:00:00 AM  2
1/3/2023 12:00:00 AM  3
1/4/2023 12:00:00 AM  4
1/5/2023 12:00:00 AM  5
1/6/2023 12:00:00 AM  6   6
1/7/2023 12:00:00 AM  7   7
1/8/2023 12:00:00 AM  8   8
1/9/2023 12:00:00 AM  9   9
1/10/2023 12:00:00 AM 10  10

下面是一个类似的、更手动的方法,使用OrderedDictionary对对象进行分组,* 可能会更高效一些 *:

$dict = [ordered]@{}
foreach($item in $listA + $listB) {
    $value = $item.Date
    if(-not $value) {
        $value = $item.D_Date
    }

    if(-not $dict.Contains($value)) {
        $dict[$value] = [System.Collections.Generic.List[object]]::new()
    }

    $dict[$value].Add($item)
}

foreach($pair in $dict.GetEnumerator()) {
    [pscustomobject]@{
        Date = $pair.Key
        AAA  = $pair.Value.AAA | Select-Object -First 1
        BBB  = $pair.Value.BBB | Select-Object -First 1
    }
}

相关问题