在PowerShell中,解析这些字符串的最佳方法是什么?

3

我正在接收两个字符串作为我的脚本参数:

"Project1,Project2,Project3,Project4"
"web,batch,web,components"

这些字符串来自我们的DevOps工具链中的一个工具,我无法控制输入格式。字符串1可以是任意数量的项目。字符串2将有相同数量的条目,其中包含字符串1中项目的“类型”。

我需要为第二个字符串中每个不同类型发出一个字符串,其中包含来自第一个字符串的项目:

"Project1,Project3"
"Project2"
"Project4"

我知道可以使用一堆嵌套的foreach循环来完成。有没有使用哈希表和/或数组的方法来完成呢?


($input | ConvertFrom-Csv).PSObject.Properties | Group-Object Value | ForEach-Object {$_.Group.Name -join ','} - user4003407
3个回答

6
你可以使用 -split 操作符将原始输入字符串转换为数组:
$ProjectNames = "Project1,Project2,Project3,Project4" -split ','
$ProjectTypes = "web,batch,web,components" -split ','

然后创建一个空的哈希表来包含类型到项目名称的映射。
$ProjectsByType = @{}

最后,遍历这两个数组,按类型将项目名称分组:
for($i = 0; $i -lt $ProjectNames.Count; $i++){
    if(-not $ProjectsByType.ContainsKey($ProjectTypes[$i])){
        # Create key and entry as array if it doesn't already exist
        $ProjectsByType[$ProjectTypes[$i]] = @()
    }
    # Add the project to the appropriate project type key
    $ProjectsByType[$ProjectTypes[$i]] += $ProjectNames[$i]
}

现在您可以按项目类型分组生成所需的字符串:
$ProjectsByType.Keys |ForEach-Object {
    $ProjectsByType[$_] -join ','
}

你也可以从这两个数组中创建对象并使用Group-Object进行分组:
$Projects = for($i = 0; $i -lt $ProjectNames.Count; $i++){
    New-Object psobject -Property @{
        Name = $ProjectNames[$i]
        Type = $ProjectTypes[$i]
    }
}

$Projects |Group-Object -Property Type

这更有趣,如果你想要进一步处理项目,但如果你只需要字符串,第一种方法更容易。

基本上我得到了我想要的,只不过更加高效。谢谢。 - Richard Schaefer
更简单的写法:$ProjectsByType[$ProjectTypes[$i]] += @($ProjectNames[$i]) - Ansgar Wiechers

5

使用内置方法没有一种优雅的方式将两个数组组合在一起。一个有些复杂的方法是以下步骤:

$projects = $projectString -split ','
$types = $typeString -split ','
0..($projects.Count) | group { $types[$_] } | % { $projects[$_.Group] -join ',' }

然而,这首先会生成数组的索引以便稍后对它们进行分组和格式化,这本质上有点靠不住(并且不太容易理解)。我倾向于预处理数据,以实际反映我正在处理的内容:

$projects = $projectString -split ','
$types = $typeString -split ','
$projectsWithType = 0..($projects.Count) | % {
  [pscustomobject]@{
    Project = $projects[$_]
    Type = $types[$_]
  }
}
$projectsWithType | group Type | % { $_.Group -join ',' }

这使得实际的数据处理任务更加清晰。

我已经得到了我所需要的答案,但我会进行一些实验来看看它是否能够为我今后需要完成的其他任务提供更多的功能。谢谢。 - Richard Schaefer

0

仅需在第一个列表中进行一次搜索

$projects = "Project1,Project2,Project3,Project4" -split ','
$types = "web,batch,web,components" -split ','

$linenumber = 0

$projects |%{New-Object psObject -Property @{Project=$_;TypeProject= $types[$linenumber]};$linenumber++} |
group TypeProject |
select Name, @{N="Projects";E={$_.Group.Project -join ","}}

这就是我想要的。一个foreach循环,但大部分都是pipeline。谢谢! - Richard Schaefer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接