Arrays 对数组中的项进行分组

Arrays 对数组中的项进行分组,arrays,powershell,split,Arrays,Powershell,Split,鉴于此阵列: @("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, "ab

鉴于此阵列:

@("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中是否有一种更惯用的方法?

当然,有一种更为idomatic的方法,但它涉及到多次连接和拆分数组和字符串,这可能会对性能产生负面影响,而且肯定更难阅读

$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
操作符的性能在以前的版本中有所不同。

嗯,有一种稍微更为自动化的方法,但它涉及多次连接和拆分数组和字符串,这可能会对性能产生负面影响,而且肯定会让人难以阅读

$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
操作符的性能在以前的版本中有所不同。

嗯,有一种稍微更为自动化的方法,但它涉及多次连接和拆分数组和字符串,这可能会对性能产生负面影响,而且肯定会让人难以阅读

$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
操作符的性能在以前的版本中有所不同。

嗯,有一种稍微更为自动化的方法,但它涉及多次连接和拆分数组和字符串,这可能会对性能产生负面影响,而且肯定会让人难以阅读

$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
操作符的性能有所不同。

这里有另一种方法:

$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

以下是另一种方法:

$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

以下是另一种方法:

$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

以下是另一种方法:

$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
在本例中,
“abc”
可以看作是一个分隔符。本例中的分组发生时,分隔符包含在组的左侧。下面是一个更一般的函数,它接受一个用于查找分隔符的谓词:

function Split-Array-Pred-Left ()
{
    param($in, $pred)

    $arrs = @()

    $arr = @()

    $in | ForEach-Object {
        if (& $pred $_) { $arrs += , $arr; $arr = @(); }
        $arr += $_
    }

    $arrs += , $arr

    $arrs
}
包含每个组右侧分隔符的类似函数是相同的,但交换了两行:

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
在本例中,
“abc”
可以看作是一个分隔符。本例中的分组发生时,分隔符包含在组的左侧。下面是一个更一般的函数,它接受一个用于查找分隔符的谓词:

function Split-Array-Pred-Left ()
{
    param($in, $pred)

    $arrs = @()

    $arr = @()

    $in | ForEach-Object {
        if (& $pred $_) { $arrs += , $arr; $arr = @(); }
        $arr += $_
    }

    $arrs += , $arr

    $arrs
}
包含每个组右侧分隔符的类似函数是相同的,但交换了两行:

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
在本例中,可以认为
“abc”