【问题标题】:Powershell Compare and Merge two arraysPowershell 比较和合并两个数组
【发布时间】:2021-05-13 12:20:41
【问题描述】:

我是 Powershell 的新手,我想做的是比较两个数据数组,然后将它们合并到一个大数组中,我可以将其导出到 Excel 或使用 RESTful API 将请求发送到 Web 服务器和json.

在 Python 中使用 Pandas 并添加搜索数据很简单,但在 Powershell 中我无法真正完成。

示例:我有 2 个数组

$a1 = @(('Name1', 'Link1', 'URL1'),
        ('Name2', 'Link2', 'URL2'),
        ('Name3', 'Link3', 'URL3')
      )

$a2 = @(('Name4', 'URL4', 'TEXT4'),
        ('Name2', 'URL2', 'TEXT1'),
        ('Name1', 'URL1', 'TEXT2')
        )

我想将$a1$a2 进行比较,反之亦然,这样我就不会错过任何值。

将它们合并在一起,这样我最终会得到一个看起来像这样的 $a3 数组。

$a3 = @(('Name1', 'Link1', 'URL1', 'TEXT1),
        ('Name2', 'Link2', 'URL2', 'TEXT2),
        ('Name3', 'Link3', 'URL3', ''),
        ('Name4', 'URL4', '', 'TEXT4')
      )

随着我对不同替代方案的深入挖掘,我会越来越困惑。

【问题讨论】:

  • 看两个数组,元素0是公共键。查看数组 $a2 行索引 2 ('Name1', 'URL1', 'TEXT2'),您期望将不匹配的键行元素根据模式合并到另一行中是否正确?
  • 您的标签:multidimensional-array - 它不是二维数组,它是数组数组,在.Net 中具有意义差异。

标签: arrays powershell multidimensional-array


【解决方案1】:

我建议制作一个(至少)简单对象的集合以供使用。 这几乎是通过通用键组合两组不同属性的经典任务。只需将这些arrays-of-arrays 转换为arrays-of-objects-with-properties,然后将它们组合起来。

请注意,powershell 是主要系统管理员的语言,在处理任务时几乎没有任何猜测或机会。

您还可以在 PowerShell 中使用几乎任何外部 .Net-DLL 库(搜索 Deedle as alternative to Pandas

$a1 = @(('Name1', 'Link1', 'URL1'),
        ('Name2', 'Link2', 'URL2'),
        ('Name3', 'Link3', 'URL3')
      )

$a2 = @(('Name4', 'URL4', 'TEXT4'),
        ('Name2', 'URL2', 'TEXT1'),
        ('Name1', 'URL1', 'TEXT2')
        )

# Make Hashtable K=Name;V={Name, Link, Url, Text}
$AObjects = @{}

# Fill Hashtable from A1
@($a1) | 
    ForEach-Object { 
        $name = $_[0]
        $AObjects[$name] = @{
            Name = $name
            Link = $_[1]
            Url  = $_[2]
            Text = ''
            }
        }
# Fill Hashtable from A2
@($a2) | 
    ForEach-Object { 
        $name = $_[0]
        $url  = $_[1]
        if (-not $AObjects.ContainsKey($name)) {
            Write-Warning "A2 has [$name] that was not listed in A1!"
            $AObjects[$name] = @{Name = $name; Url = $url; Link = ''; Text = ''}
        } elseif($AObjects[$name].Url -ne $url) {
            Write-Warning "For $($name), A1's URL and A2's URL differ! Using A1's"
        }
        $AObjects[$name].Text = $_[2]
    }

# Convert Hashtable to array of objects with props. Select is required for better output.
$AObjects = @($AObjects.Values) | % { [PSCustomObject]$_ } | Select-Object @('Name', 'Link', 'URL', 'Text')

# Convert array of objects with props back to array
$result = $AObjects | 
    ForEach-Object {
        if ([string]::IsNullOrWhiteSpace($_.Link)) {  # Didn't get your logic swapping elements in example
            return @(,@($_.Name, $_.Url, $_.Link, $_.Text))
        } else {
            return @(,@($_.Name, $_.Link, $_.Url, $_.Text))
        }
    }

#Print
$result | % { "[$($_ -join ',')]" }

# [Name3,Link3,URL3,]
# [Name1,Link1,URL1,TEXT2]
# [Name2,Link2,URL2,TEXT1]
# [Name4,URL4,,TEXT4]

【讨论】:

  • 您可以使用 Linq 执行排序,如 post
猜你喜欢
  • 2013-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-21
相关资源
最近更新 更多