PowerShell 中的字符串比较似乎不起作用

发布于 2025-01-13 00:36:04 字数 1237 浏览 0 评论 0原文

我正在尝试将一个数组中的字符串与另一个数组中的每个字符串进行比较。当前的方法是有效的,因为我已经使用更简单的变量对其进行了测试,并且它可以正确地检索它们。但是,我需要它进行比较的字符串似乎不受比较的影响。

该方法如下:

$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 $_}

任何人都可以发现我在任何地方可能犯的错误吗?

I am trying to compare strings from one array to every string from the other. The current method works, as I have tested it with simpler variables and it retrieves them correctly. However, the strings that I need it to compare don't seem to be affected by the comparison.

The method is the following:

$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
          }
     }
}

For each string in the first array it is iterating between all strings in the second and comparing them. If it locates equality, it breaks and goes to the next string in the first array. If it doesn't, for each inequality it is adding to the counter and whenever the counter hits the length of the second array (meaning no equality has been located in the second array) it adds the corresponding string to a third array that is supposed to retrieve all strings that don't match to anything in the second array in the end. Then the counter is set to 0 again and it breaks so that it can go to the next string from the first array.

This is all okay in theory and also works in practice with simpler strings, however the strings that I need it to work with are server IDs and look like this:

289101b4-3e6c-4495-9c67-f317589ba92c

Hence, the script seems to completely ignore the comparison and just puts all the strings from the first array into the third one and retrieves them at the end (sometimes also some random strings from both first and second array).

Another method I tried with similar results was:

$unmatching_serverids = $serverid_oc_arr | Where {$moss_serverid_arr -NotContains $_}

Can anyone spot any mistake that I may be making anywhere?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

浅浅 2025-01-20 00:36:04

您的代码的问题主要是使用 -le 而不是 -lt,集合索引从 0 开始,集合的 LengthCount 属性从 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(..) 方法 来自 HashSet;类:

$hash = [System.Collections.Generic.HashSet[guid]]::new([guid[]]$arr1)
$hash.ExceptWith([guid[]]$arr2)
$hash.Count -eq 10 # => `$true`

The issue with your code is mainly the use of -le instead of -lt, collection index starts at 0 and the collection's Length or Count property starts at 1. This was causing $null values being added to your result collection.

In addition to the above, $counter was never getting reset if the following condition was not met:

if ($counter -eq $moss_serverid_arr.Length) { ... }

You would need to a add a $counter = 0 outside inner for loop to prevent this.

Below you can find the same, a little bit improved, algorithm in addition to a test case that proves it's working.

$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`

As side, the above could be reduced to this using the .ExceptWith(..) method from HashSet<T> Class:

$hash = [System.Collections.Generic.HashSet[guid]]::new([guid[]]$arr1)
$hash.ExceptWith([guid[]]$arr2)
$hash.Count -eq 10 # => `$true`
浅紫色的梦幻 2025-01-20 00:36:04

我为此找到的有效答案如下:

$unmatching_serverids = @()
foreach ($item in $serverid_oc_arr)
{
    if ($moss_serverid_arr -NotContains $item)
    {
    $unmatching_serverids += $item
    }
}

它和其他​​方法之间没有明显的差异(特别是对于 for 循环,这只是一个简化的变体),但不知何故它工作正常。

The working answer that I found for this is the below:

$unmatching_serverids = @()
foreach ($item in $serverid_oc_arr)
{
    if ($moss_serverid_arr -NotContains $item)
    {
    $unmatching_serverids += $item
    }
}

No obvious differences can be seen between it and the other methods (especially for the for-loop, this is just a simplified variant), but somehow this works correctly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文