我很难在Powershell中完成笛卡尔积算法。使用stackoverflow中的其他公式,这就是我提出的:
clear
Function New-GenericDictionary([type] $keyType, [type]$valueType)
{
$base = [System.Collections.Generic.Dictionary``2]
$ct = $base.MakeGenericType(($keyType, $valueType))
New-Object $ct
}
$sets = New-GenericDictionary int string
$sets[0] = "1"
$sets[1] = "0,1"
$sets[2] = "0,1"
$iterations = 1
$stringCombo = ""
foreach($key in $sets.Keys) {
$pieces = $sets[$key].Split(",")
$iterations = $iterations * $pieces.Length
}
for ($i = 0; $i -lt $iterations; $i++) {
$stringCombo = ""
foreach($key in $sets.Keys) {
$pieces = $sets[$key].Split(",")
$val = $pieces.Length
$get = $i%$val
$stringCombo = $stringCombo + " " + $pieces[$get]
}
Write-Host $stringCombo.Trim()
}
#output hoped for:
#1 0 0
#1 0 1
#1 1 0
#1 1 1
#output is:
#1 0 0
#1 1 1
#1 0 0
#1 1 1
如代码片段底部的注释中所示,输出并未产生预期的结果。迭代计数返回正确的值但组合未正确完成。
在这个片段中,$ sets [x]是固定的,但在实际的脚本中,$ sets字典项是作为循环的一部分创建的,每次迭代可以包含1到多个项目。
有人可以提供第二组眼睛向我展示我错过了什么吗?
由于
答案 0 :(得分:1)
我认为你不需要通用词典。一对简单的数组就可以了:
PS> $c1 = 0,1
PS> $c2 = 0,1
PS> foreach ($i in $c1) {
>> foreach ($j in $c2) {
>> "$i,$j"
>> }
>> }
>>
0,0
0,1
1,0
1,1
答案 1 :(得分:1)
我想要一个单行程来获得每个独特的组合。例如,用a,b,c得到 a,b a,c b,c
这就是我提出的
function pairwise($list) { $i = 0; $list | % { foreach ($li in ($list | select -Skip (++$i))) { new-object PSObject -Property @{Left=$_;Right=$li} } } }
答案 2 :(得分:1)
我的尝试足以满足我的需求:
function Get-CartesianProduct {
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
[object[]] $List1,
[Parameter(Mandatory = $true)]
[object[]] $List2)
process {
$List1 |
%{
$Item1 = $_
$List2 |
%{
$Item2 = $_
@{
Item1 = $Item1
Item2 = $Item2
}
}
}
}
}
Get-CartesianProduct 'Apple','Rhubarb','Chocolate' 'Pie','Cake' |
%{
write-host $_.Item1 $_.Item2
}
答案 3 :(得分:0)
不漂亮,但是n列表的技巧
# ------------------------------------------------------------------------------
<#
CartesianProduct-Lists
#>
# ------------------------------------------------------------------------------
function CartesianProduct-Lists
{
param
(
$Lists
)
function Make-List
{
param
(
$Head, $Tail
)
if ($Head -is [Object[]])
{
# List already so just extend
$Result = $Head + $Tail
}
else
{
# Create List
$Result = @($Head, $Tail)
}
,$Result
}
# if Head..Tail
if (@($Lists).Count -gt 1)
{
$Head = $Lists[0]
$Next = $Lists[1]
$Result = @()
foreach ($HeadItem in $Head)
{
foreach ($NextItem in $Next)
{
$Result += ,(Make-List $HeadItem $NextItem)
}
}
if (@($Lists).Count -gt 2)
{
$Index = $Lists.Count - 1
$Tail = $Lists[2..$Index]
$Result = ,$Result + $Tail
$Result = CartesianProduct-Lists $Result
}
,$Result
}
}
# --------------------------------------------------------
$Lists = @(@(1),@(0,1),@(0,1))
$Result = CartesianProduct-Lists $Lists
$Result | % { $_; "" }
产量
1 0 0
1 0 1
1 1 0
1 1 1
答案 4 :(得分:0)
改进版本
# ------------------------------------------------------------------------------
<#
CartesianProduct-Lists
#>
# ------------------------------------------------------------------------------
function CartesianProduct-Lists
{
param
(
$Lists
)
function Make-List
{
param
(
$Head, $Tail
)
if ($Tail -is [Object[]])
{
# List already so just extend
$Result = ,$Head + $Tail
}
else
{
# Create List
$Result = @($Head, $Tail)
}
,$Result
}
switch (,$Lists) {
$Null
{
break
}
# 1 List so just return it
{ $_.Count -eq 1 }
{
$_
}
# More than one list so recurse
{ $_.Count -gt 1 }
{
$Head = $_[0]
$Index = $_.Count - 1
$Tail = $_[1..$Index]
$Next = CartesianProduct-Lists $Tail
$Result = @()
foreach ($HeadItem in $Head)
{
foreach ($NextItem in $Next)
{
$Result += ,(Make-List $HeadItem $NextItem)
}
}
,$Result
}
}
}