我正在尝试将一个数组中的字符串与另一个数组中的每个字符串进行比较。当前的方法是有效的,因为我已经使用更简单的变量对其进行了测试,并且它可以正确地检索它们。但是,我需要它比较的字符串似乎不受比较的影响。
方法如下:
$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) { ... }
您需要添加 $counter = 0
外部内部 for 循环可以防止这种情况发生。
下面您可以找到相同的算法,稍微改进,以及证明其有效的测试用例。
$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 将上面的内容简化为这样来自 HashSet<T>
Class :
$hash = [System.Collections.Generic.HashSet[guid]]::new([guid[]]$arr1)
$hash.ExceptWith([guid[]]$arr2)
$hash.Count -eq 10 # => `$true`
关于arrays - PowerShell 中的字符串比较似乎不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71417885/