来自 powershell 阵列的独特组合 - 没有重复的组合
Unique Combos from powershell array - No duplicate combos
我正在尝试找出从 powershell 数组中获取独特组合的最佳方法。例如,我的数组可能是
@(B,C,D,E)
我希望得到这样的输出:
B
C
D
E
B,C
B,D
B,E
C,D
C,E
D,E
B,C,D
C,D,E
B,C,D,E
我不想重新安排组合。如果组合 C、D 已经存在,那么我不想要组合 D、C。这对我来说是多余的。
我查看了这里的函数:Get all combinations of an array
但它们不是我想要的。我一直在努力自己解决这个问题,但花了很多时间都没有成功。我想我会在这里问这个问题,这样如果其他人已经知道我不会在浪费时间。
谢谢!
我对此的疲惫尝试。我确实设法让它产生了预期的结果,但它是如何做到的并不那么优雅。使用递归功能。
Function Get-Permutations{
Param(
$theInput
)
$theInput | ForEach-Object{
$element = $_
$sansElement = ($theInput | Where-Object{$_ -ne $element})
If($sansElement.Count -gt 1){
# Build a collection of permutations using the remaining elements that were not isolated in this pass.
# Use the single element since it is a valid permutation
$perms = ,$element
For($elementIndex = 0;$elementIndex -le ($sansElement.Count - 1);$elementIndex++){
$perms += ,@(,$element + $sansElement[0..$elementIndex] | sort-object)
}
# For loop does not send to output properly so that is the purpose of collecting the results of this pass in $perms
$perms
# If there are more than 2 elements in $sansElement then we need to be sure they are accounted for
If($sansElement -gt 2){Get-Permutations $sansElement}
}
}
}
Get-Permutations B,C,D,E | %{$_ -join ","} | Sort-Object -Unique
我希望我能解释清楚自己....所以函数的每次传递都会接受一个数组。该数组的每个单独元素都将与由变量 $element
和 $sansElement
.
表示的数组的其余部分隔离
使用这些变量,我们构建了由这些元素组成的独立且逐渐变大的数组。让这个例子显示使用数组 1,2,3,4
1
1,2
1,2,3
1,2,3,4
以上每个"number"
2
2,1
2,1,3
2,1,3,4
等等。如果 returned 数组包含两个以上的元素(1,2
将与您示例中的 2,1
相同,因此我们不关心超过一个匹配项的对)我们将采用该数组和 运行 它通过相同的功能。
真正的问题是这里的逻辑(我知道这可能难以接受)创建了多个重复项。我想你可以创建一个哈希表,我将探索它,但它不会消除逻辑缺陷。
不管我如何自责,只要你没有成千上万的元素,这个过程仍然会产生结果。
Get-Permutations
会 return 和数组数组。 PowerShell 将每行显示一个元素。您要求以逗号分隔的输出,这是 -join
出现的地方。Sort-Object -Unique
接受那些排序的字符串并丢弃重复项。
示例输出
B
B,C
B,C,D
B,C,D,E
B,C,E #< Missing from your example output.
B,D
B,D,E #< Missing from your example output.
B,E
C
C,D
C,D,E
C,E
D
E
这是对 C# 解决方案的改编 class 我认为它问了同样的问题。对于任何集合,找到所有子集,包括空集。
function Get-Subsets ($a){
#uncomment following to ensure only unique inputs are parsed
#e.g. 'B','C','D','E','E' would become 'B','C','D','E'
#$a = $a | Select-Object -Unique
#create an array to store output
$l = @()
#for any set of length n the maximum number of subsets is 2^n
for ($i = 0; $i -lt [Math]::Pow(2,$a.Length); $i++)
{
#temporary array to hold output
[string[]]$out = New-Object string[] $a.length
#iterate through each element
for ($j = 0; $j -lt $a.Length; $j++)
{
#start at the end of the array take elements, work your way towards the front
if (($i -band (1 -shl ($a.Length - $j - 1))) -ne 0)
{
#store the subset in a temp array
$out[$j] = $a[$j]
}
}
#stick subset into an array
$l += -join $out
}
#group the subsets by length, iterate through them and sort
$l | Group-Object -Property Length | %{$_.Group | sort}
}
这样使用:
PS C:>Get-Subsets @('b','c','d','e')
b
c
d
e
bc
bd
be
cd
ce
de
bcd
bce
bde
cde
bcde
请注意,计算成本随输入数组的长度呈指数增长。
Elements SecondstoComplete
15 46.3488228
14 13.4836299
13 3.6316713
12 1.2542701
11 0.4472637
10 0.1942997
9 0.0867832
我正在尝试找出从 powershell 数组中获取独特组合的最佳方法。例如,我的数组可能是
@(B,C,D,E)
我希望得到这样的输出:
B
C
D
E
B,C
B,D
B,E
C,D
C,E
D,E
B,C,D
C,D,E
B,C,D,E
我不想重新安排组合。如果组合 C、D 已经存在,那么我不想要组合 D、C。这对我来说是多余的。
我查看了这里的函数:Get all combinations of an array
但它们不是我想要的。我一直在努力自己解决这个问题,但花了很多时间都没有成功。我想我会在这里问这个问题,这样如果其他人已经知道我不会在浪费时间。
谢谢!
我对此的疲惫尝试。我确实设法让它产生了预期的结果,但它是如何做到的并不那么优雅。使用递归功能。
Function Get-Permutations{
Param(
$theInput
)
$theInput | ForEach-Object{
$element = $_
$sansElement = ($theInput | Where-Object{$_ -ne $element})
If($sansElement.Count -gt 1){
# Build a collection of permutations using the remaining elements that were not isolated in this pass.
# Use the single element since it is a valid permutation
$perms = ,$element
For($elementIndex = 0;$elementIndex -le ($sansElement.Count - 1);$elementIndex++){
$perms += ,@(,$element + $sansElement[0..$elementIndex] | sort-object)
}
# For loop does not send to output properly so that is the purpose of collecting the results of this pass in $perms
$perms
# If there are more than 2 elements in $sansElement then we need to be sure they are accounted for
If($sansElement -gt 2){Get-Permutations $sansElement}
}
}
}
Get-Permutations B,C,D,E | %{$_ -join ","} | Sort-Object -Unique
我希望我能解释清楚自己....所以函数的每次传递都会接受一个数组。该数组的每个单独元素都将与由变量 $element
和 $sansElement
.
使用这些变量,我们构建了由这些元素组成的独立且逐渐变大的数组。让这个例子显示使用数组 1,2,3,4
1
1,2
1,2,3
1,2,3,4
以上每个"number"
2
2,1
2,1,3
2,1,3,4
等等。如果 returned 数组包含两个以上的元素(1,2
将与您示例中的 2,1
相同,因此我们不关心超过一个匹配项的对)我们将采用该数组和 运行 它通过相同的功能。
真正的问题是这里的逻辑(我知道这可能难以接受)创建了多个重复项。我想你可以创建一个哈希表,我将探索它,但它不会消除逻辑缺陷。
不管我如何自责,只要你没有成千上万的元素,这个过程仍然会产生结果。
Get-Permutations
会 return 和数组数组。 PowerShell 将每行显示一个元素。您要求以逗号分隔的输出,这是 -join
出现的地方。Sort-Object -Unique
接受那些排序的字符串并丢弃重复项。
示例输出
B
B,C
B,C,D
B,C,D,E
B,C,E #< Missing from your example output.
B,D
B,D,E #< Missing from your example output.
B,E
C
C,D
C,D,E
C,E
D
E
这是对 C# 解决方案的改编 class 我认为它问了同样的问题。对于任何集合,找到所有子集,包括空集。
function Get-Subsets ($a){
#uncomment following to ensure only unique inputs are parsed
#e.g. 'B','C','D','E','E' would become 'B','C','D','E'
#$a = $a | Select-Object -Unique
#create an array to store output
$l = @()
#for any set of length n the maximum number of subsets is 2^n
for ($i = 0; $i -lt [Math]::Pow(2,$a.Length); $i++)
{
#temporary array to hold output
[string[]]$out = New-Object string[] $a.length
#iterate through each element
for ($j = 0; $j -lt $a.Length; $j++)
{
#start at the end of the array take elements, work your way towards the front
if (($i -band (1 -shl ($a.Length - $j - 1))) -ne 0)
{
#store the subset in a temp array
$out[$j] = $a[$j]
}
}
#stick subset into an array
$l += -join $out
}
#group the subsets by length, iterate through them and sort
$l | Group-Object -Property Length | %{$_.Group | sort}
}
这样使用:
PS C:>Get-Subsets @('b','c','d','e')
b
c
d
e
bc
bd
be
cd
ce
de
bcd
bce
bde
cde
bcde
请注意,计算成本随输入数组的长度呈指数增长。
Elements SecondstoComplete
15 46.3488228
14 13.4836299
13 3.6316713
12 1.2542701
11 0.4472637
10 0.1942997
9 0.0867832