鉴于此数组:
@("abc", 5, 4, 2, 7, 6, 5, 4, "abc", 7, 9, 3, "abc", 3, 2, 4)
我想最终得到一个阵列数组:
@("abc", 5, 4, 2, 7, 6, 5, 4)
@("abc", 7, 9, 3)
@("abc", 3, 2, 4)
即。将原始数组拆分为多个组,每个组包括“abc”以及跟随它到下一个“abc”或数组末尾的项目。
这是一种方法:
$result = @("abc", 5, 4, 2, 7, 6, 5, 4, "abc", 7, 9, 3, "abc", 3, 2, 4)
$arrs = @()
$arr = @()
$result | ForEach-Object {
if ($_ -eq 'abc')
{
if ($arr.Count -gt 0) { $arrs += , $arr }
$arr = @()
}
$arr += $_
}
$arrs += , $arr
PowerShell中有更惯用的方法吗?
答案 0 :(得分:2)
这是另一种方法:
$r = @("abc", 5, 4, 2, 7, 6, 5, 4, "abc", 7, 9, 3, "abc", 3, 2, 4) |
Foreach -Begin {$arr=$null} -Process {if ($_ -eq 'abc') {,$arr; $arr = @('abc')} else {$arr += @($_)}} -End {,$arr} |
Where {$_}
$r[0]
输出:
abc
5
4
2
7
6
5
4
答案 1 :(得分:1)
嗯,有一种稍微更具风格的方法,但它涉及多次连接和分割数组和字符串,这可能会对性能产生负面影响,并且肯定更难以阅读。
$result = @("abc", 5, 4, 2, 7, 6, 5, 4, "abc", 7, 9, 3, "abc", 3, 2, 4)
$arrays = $result -join "," -split "abc" | ? { $_ } | % {,($_ -split ",")}
只有当您的数据点永远不会偏离"abc",1,2,3
格式时才会有效。
我们首先用逗号连接整个数组,然后在文本分隔符上拆分,然后丢弃任何空结果。如果我们不丢弃,拆分将根据拆分时有n + 1个拆分数组的事实给你一个空数组,即使它找到的第一个项是拆分字符串。
现在我们有n个字符串代表我们的数据集。循环遍历这些,将它们分开在逗号上以获取您的各个数组。对于您提供的示例集,此代码段将给出:
@(5,4,2,7,6,5,4)
@(7,9,3)
@(3,2,4)
现在,如果您希望文本分隔符位于数组的开头,请将命令更改为:
$arrays = $result -join "," -split "abc" | ? { $_ } | % {,("abc" + $_ -split ",")}
您的里程可能会有所不同,因为我仅在PowerShell 4上对此进行了测试,但我不记得-split
和-join
运算符的性能在以前的版本中有所不同。
答案 2 :(得分:0)
在示例中,"abc"
可以被视为分隔符。示例中的分组发生使得分隔符包含在组的 left 中。这里的函数更为通用,因为它接受用于查找分隔符的谓词:
function Split-Array-Pred-Left ()
{
param($in, $pred)
$arrs = @()
$arr = @()
$in | ForEach-Object {
if (& $pred $_) { $arrs += , $arr; $arr = @(); }
$arr += $_
}
$arrs += , $arr
$arrs
}
一个类似的函数,包括每个组的 right 的分隔符是相同的,但有两行交换:
function Split-Array-Pred-Right ()
{
param($in, $pred)
$arrs = @()
$arr = @()
$in | ForEach-Object {
$arr += $_
if (& $pred $_) { $arrs += , $arr; $arr = @(); }
}
$arrs += , $arr
$arrs
}
示例:
PS C:\Users\dharmatech> $result = @(4, "abc", 1, 7, 5, "abc", 7, 2, 5, 4, "abc", 8, 7)
PS C:\Users\dharmatech> Split-Array-Pred-Left $result { param($elt) $elt -like 'abc' } | ForEach-Object { $_; '' }
4
abc
1
7
5
abc
7
2
5
4
abc
8
7
PS C:\Users\dharmatech> Split-Array-Pred-Right $result { param($elt) $elt -like 'abc' } | ForEach-Object { $_; '' }
4
abc
1
7
5
abc
7
2
5
4
abc
8
7