如何将数组中的每个元素与Powershell中多个其他数组中的每个元素组合在一起

时间:2018-04-12 19:04:05

标签: arrays powershell

在Powershell中,我试图将几个数组的元素组合在一起,以创建一个独特字符串数组。我需要将每个数组中的每个元素与其他数组中的每个元素组合在一起。很难简明扼要地解释我的意思,因此可能更容易展示。

我从一个看起来像这样的二维数组开始:

thisA1that
thisA2that
thisA3that
thisA4that
thisB1that
thisB2that
thisB3that
thisB4that
thisC1that
thisC2that
thisC3that
thisC4that

我需要创建一个数组,其内容如下所示:

$tempList = @()

#get total number of resources that will be created
$total = 1
for($i=0; $i -lt $array.Count; $i++){$total = $total * $array[$i].Count}

# build each resource from permutations of array parts
for ($i = 0; $i -lt $array.Count; $i++)
{

    for ($j = 0; $j -lt $total; $j++)
    {
        $tempList += @('')
        $idx = $total % $array[$i].Count
        # item may either be string or an array. If string, just add it. If array, add the item at the index
        if ($array[$i] -is [array]){ $tempList[$j] += $array[$i][$idx] }
        else { $tempList[$j] += $array[$i] }
    }

}

原始数组中数组的长度和数量是可变的,我不知道原始数组中项目的顺序。

到目前为止,我已经尝试了一些方法,但我的逻辑错了。这是我第一次尝试解决方案:

{{1}}

在这个例子中,我的模数运算符的逻辑是错误的,所以它每次都会抓住每个数组的第一个索引。经过进一步考虑,即使我修复了模数逻辑,整体逻辑仍然是错误的。例如,如果后两个阵列的大小相同,我会得到A'与' 1'配对每一次,' B'与' 2'等

我确定有办法做到这一点,但我似乎无法看到它。

2 个答案:

答案 0 :(得分:4)

我认为答案是使用递归,因此您可以处理数组数组可以是任意长度的事实。这个递归函数应该:

  • 从数组数组中取出第一个数组
  • 遍历第一个数组中的每个项目
  • 如果第一个数组也是最后一个数组,则只返回每个项目。
  • 如果数组数组中有更多数组,则将剩余数组传递给递归函数
  • 对于递归函数的每个结果,将返回值作为第一个数组中当前项的前缀。

我认为代码比上面解释得更好:

function Combine-Array {
    [CmdletBinding()]
    Param (
        [string[][]]$Array
    )
    Process {
        $current = $Array[0]
        foreach ($item in $current) {
            if ($Array.Count -gt 1) {
                Combine-Array ([string[][]]@($Array | Select -Skip 1)) | %{'{0}{1}' -f $item, $_}
            } else {
                $item
            }
        }
    }
}

Combine-Array  @('this', ('A','B','C'), ('1','2','3','4'), 'that')

答案 1 :(得分:3)

您可以编写管道功能,这将在混合中添加一个子阵列。然后你将它称为你拥有的子阵列的次数:

function CartesianProduct {
    param(
        [array] $a
    )
    filter f {
        $i = $_
        $a[$MyInvocation.PipelinePosition - 1] | ForEach-Object { $i + $_ }
    }
    Invoke-Expression ('''''' + ' | f' * $a.Length)
}

CartesianProduct ('this', ('A','B','C'), ('1','2','3','4'), 'that')