PowerShell 中的字符串比较似乎不起作用
String comparison in PowerShell doesn't seem to work
我正在尝试将一个数组中的字符串与另一个数组中的每个字符串进行比较。当前方法有效,因为我已经使用更简单的变量对其进行了测试,并且可以正确检索它们。但是,我需要它比较的字符串似乎不受比较的影响。
方法如下:
$counter = 0
for ($num1 = 0; $num1 -le $serverid_oc_arr.Length; $num1++) {
for ($num2 = 0; $num2 -le $moss_serverid_arr.Length; $num2++) {
if ($serverid_oc_arr[$num1] -eq $moss_serverid_arr[$num2]) {
break
}
else {
$counter += 1
}
if ($counter -eq $moss_serverid_arr.Length) {
$unmatching_serverids += $serverid_oc_arr[$num1]
$counter = 0
break
}
}
}
对于第一个数组中的每个字符串,它在第二个数组中的所有字符串之间迭代并比较它们。如果它找到相等性,它就会中断并转到第一个数组中的下一个字符串。如果不是,对于每个不等式,它都会添加到计数器中,并且每当计数器达到第二个数组的长度时(意味着第二个数组中没有找到等式),它会将相应的字符串添加到第三个数组中最后检索与第二个数组中的任何内容都不匹配的所有字符串。然后计数器再次设置为 0 并中断,以便它可以从第一个数组转到下一个字符串。
这在理论上没问题,在实践中也适用于更简单的字符串,但我需要它处理的字符串是服务器 ID,如下所示:
289101b4-3e6c-4495-9c67-f317589ba92c
因此,脚本似乎完全忽略了比较,只是将第一个数组中的所有字符串放入第三个数组中,并在最后检索它们(有时还会从第一个和第二个数组中提取一些随机字符串)。
我尝试过的另一种方法具有类似的结果:
$unmatching_serverids = $serverid_oc_arr | Where {$moss_serverid_arr -NotContains $_}
任何人都可以发现我可能犯的任何错误吗?
您的代码的问题主要是使用 -le
而不是 -lt
,集合索引从 0
开始,集合的 Length
或 Count
属性 从 1
开始。这导致 $null
个值被添加到您的结果集合中。
除上述情况外,如果不满足以下条件,$counter
将永远不会被重置:
if ($counter -eq $moss_serverid_arr.Length) { ... }
您需要在外部内部 for 循环中添加 $counter = 0
以防止出现这种情况。
您可以在下面找到相同的算法,稍有改进,算法以及证明其正常工作的测试用例。
$ran = [random]::new()
$ref = [System.Collections.Generic.HashSet[int]]::new()
# generate a 100 GUID collection
$arr1 = 1..100 | ForEach-Object { [guid]::NewGuid() }
# pick 90 unique GUIDs from arr1
$arr2 = 1..90 | ForEach-Object {
do {
$i = $ran.Next($arr1.Count)
} until($ref.Add($i))
$arr1[$i]
}
$result = foreach($i in $arr1) {
$found = foreach($z in $arr2) {
if ($i -eq $z) {
$true; break
}
}
if(-not $found) { $i }
}
$result.Count -eq 10 # => Must be `$true`
作为边,上面可以使用 .ExceptWith(..)
method from HashSet<T>
Class:
$hash = [System.Collections.Generic.HashSet[guid]]::new([guid[]]$arr1)
$hash.ExceptWith([guid[]]$arr2)
$hash.Count -eq 10 # => `$true`
我为此找到的有效答案如下:
$unmatching_serverids = @()
foreach ($item in $serverid_oc_arr)
{
if ($moss_serverid_arr -NotContains $item)
{
$unmatching_serverids += $item
}
}
它与其他方法(特别是 for-loop,这只是一个简化的变体)之间没有明显区别,但不知何故它工作正常。
我正在尝试将一个数组中的字符串与另一个数组中的每个字符串进行比较。当前方法有效,因为我已经使用更简单的变量对其进行了测试,并且可以正确检索它们。但是,我需要它比较的字符串似乎不受比较的影响。
方法如下:
$counter = 0
for ($num1 = 0; $num1 -le $serverid_oc_arr.Length; $num1++) {
for ($num2 = 0; $num2 -le $moss_serverid_arr.Length; $num2++) {
if ($serverid_oc_arr[$num1] -eq $moss_serverid_arr[$num2]) {
break
}
else {
$counter += 1
}
if ($counter -eq $moss_serverid_arr.Length) {
$unmatching_serverids += $serverid_oc_arr[$num1]
$counter = 0
break
}
}
}
对于第一个数组中的每个字符串,它在第二个数组中的所有字符串之间迭代并比较它们。如果它找到相等性,它就会中断并转到第一个数组中的下一个字符串。如果不是,对于每个不等式,它都会添加到计数器中,并且每当计数器达到第二个数组的长度时(意味着第二个数组中没有找到等式),它会将相应的字符串添加到第三个数组中最后检索与第二个数组中的任何内容都不匹配的所有字符串。然后计数器再次设置为 0 并中断,以便它可以从第一个数组转到下一个字符串。
这在理论上没问题,在实践中也适用于更简单的字符串,但我需要它处理的字符串是服务器 ID,如下所示:
289101b4-3e6c-4495-9c67-f317589ba92c
因此,脚本似乎完全忽略了比较,只是将第一个数组中的所有字符串放入第三个数组中,并在最后检索它们(有时还会从第一个和第二个数组中提取一些随机字符串)。
我尝试过的另一种方法具有类似的结果:
$unmatching_serverids = $serverid_oc_arr | Where {$moss_serverid_arr -NotContains $_}
任何人都可以发现我可能犯的任何错误吗?
您的代码的问题主要是使用 -le
而不是 -lt
,集合索引从 0
开始,集合的 Length
或 Count
属性 从 1
开始。这导致 $null
个值被添加到您的结果集合中。
除上述情况外,如果不满足以下条件,$counter
将永远不会被重置:
if ($counter -eq $moss_serverid_arr.Length) { ... }
您需要在外部内部 for 循环中添加 $counter = 0
以防止出现这种情况。
您可以在下面找到相同的算法,稍有改进,算法以及证明其正常工作的测试用例。
$ran = [random]::new()
$ref = [System.Collections.Generic.HashSet[int]]::new()
# generate a 100 GUID collection
$arr1 = 1..100 | ForEach-Object { [guid]::NewGuid() }
# pick 90 unique GUIDs from arr1
$arr2 = 1..90 | ForEach-Object {
do {
$i = $ran.Next($arr1.Count)
} until($ref.Add($i))
$arr1[$i]
}
$result = foreach($i in $arr1) {
$found = foreach($z in $arr2) {
if ($i -eq $z) {
$true; break
}
}
if(-not $found) { $i }
}
$result.Count -eq 10 # => Must be `$true`
作为边,上面可以使用 .ExceptWith(..)
method from HashSet<T>
Class:
$hash = [System.Collections.Generic.HashSet[guid]]::new([guid[]]$arr1)
$hash.ExceptWith([guid[]]$arr2)
$hash.Count -eq 10 # => `$true`
我为此找到的有效答案如下:
$unmatching_serverids = @()
foreach ($item in $serverid_oc_arr)
{
if ($moss_serverid_arr -NotContains $item)
{
$unmatching_serverids += $item
}
}
它与其他方法(特别是 for-loop,这只是一个简化的变体)之间没有明显区别,但不知何故它工作正常。