【发布时间】:2017-09-26 15:18:09
【问题描述】:
我有两个存储在变量中的列表:$list1 和 $list2,例如:
$list1:
$list2:
如何将它们逐行合并在一起,最终得到:
a1 b2 c3 d4我尝试过使用数组 (@),但它只是将它们一个接一个地组合在一起,而不是逐行组合,例如:
$list1 = @(command)
$list1 += @($list2)
【问题讨论】:
标签: list powershell merge
我有两个存储在变量中的列表:$list1 和 $list2,例如:
$list1:
$list2:
如何将它们逐行合并在一起,最终得到:
a1 b2 c3 d4我尝试过使用数组 (@),但它只是将它们一个接一个地组合在一起,而不是逐行组合,例如:
$list1 = @(command)
$list1 += @($list2)
【问题讨论】:
标签: list powershell merge
您可以使用 For 循环来执行此操作,该循环使用迭代每个对象的索引,直到达到第一个对象的总数 (.count):
$list1 = 'a','b','c','d'
$list2 = 1,2,3,4
For ($i=0; $i -lt $list1.count; $i++) {
$list1[$i]+$list2[$i]
}
输出:
a1
b2
c3
d4
如果您希望将结果转到变量中,可以将(例如)$list = 放在 For 之前。
【讨论】:
如果你更喜欢流水线,你也可以在一行中完成:
0 .. ($list1.count -1) | ForEach-Object { $list1[$_]+$list2[$_] }
【讨论】:
$list1 只是一个字符串。正确的方式是:$list1 = 'a', 'b', 'c', 'd'
补充Mark Wragg's helpful for-based answer和Martin Brandl's helpful pipeline-based answer:
将foreach 与.. 结合使用,范围运算符可以提供一个简洁的解决方案,而且性能也很好:
foreach ($i in 0..($list1.count-1)) { "$($list1[$i])$($list2[$i])" }
尽管首先构造了整个索引数组 - 0..($list1.count-1) - 这在具有大输入列表的情况下略微优于 for 解决方案,并且 foreach 和 for 都将明显快于基于管道的解决方案- 见下文。
还要注意如何使用字符串插值(单个"..." 字符串中的变量引用和子表达式)来确保结果始终是字符串。
相比之下,如果您使用+,则决定输出类型的是LHS的类型,这可能会导致错误或不需要的输出;例如,1 + 'a' 会导致错误,因为1 是整数,而'a' 无法转换为整数。
通常,foreach 和 for 解决方案明显快于基于管道(ForEach-Object 基于 cmdlet)的解决方案。
流水线优雅简洁,但相对较慢。
这不应该阻止您使用它们,但重要的是要意识到它们可能成为性能瓶颈。
管道内存效率很高,并且对于处理不适合整个内存的大型集合,它们始终是正确的工具。
PSv4 引入了鲜为人知的.ForEach()集合运算符(方法),其性能介于for / foreach 和ForEach-Object 之间 cmdlet.
下面比较大列表(100,000 项)的相对性能;绝对时间数字会因许多因素而异,但它们应该让您大致了解:
# Define two large lists.
$list1 = 1..100000
$list2 = 1..100000
# Define the commands as script blocks:
$cmds = { foreach ($i in 0..($list1.count-1)) { "$($list1[$i])$($list2[$i])" } },
{ for ($i=0; $i -lt $list1.count; $i++) { "$($list1[$i])$($list2[$i])" } },
{ 0..($list1.count -1) | ForEach-Object { "$($list1[$_])$($list2[$_])" } },
{ (0..($list1.count-1)).ForEach({ "$($list1[$_])$($list2[$_])" }) }
# Time each command.
$cmds | ForEach-Object { '{0:0.0}' -f (Measure-Command $_).TotalSeconds }
在运行 PSv5.1 的 2 核 Windows 10 虚拟机中,我在多次运行测试后得到以下结果:
0.5 # foreach
0.7 # for
1.8 # ForEach-Object (pipeline)
1.2 # .ForEach() operator
【讨论】: