【问题标题】:Is -and comparison evaluated individually or against the same object?-and 比较是单独评估还是针对同一个对象评估?
【发布时间】:2019-12-10 01:32:19
【问题描述】:

我正在寻找两个数组之间的缺失事件:$tc_records & $RelationshipEvents_array。两个数组应该有相同的两个条目。

A->B 和反向 B->A 的条目。当我使用-and 语句评估RelationshipEvents 时,是否评估一个(相同)事件,或者-and 的每一侧加载数组并独立评估。

foreach ($record in $tc_records) {
    # is this using the same RelationshipEvent for both comparisons or two different comparisons?
    if($RelationshipEvents_array.entity1Id -eq $record.entity1Id -and $RelationshipEvents_array.entity2Id -eq $record.entity2Id){
        $re_tc_matched_record.Add($record)
    } else {
        $re_tc_not_matched_record.Add($record)
    }    
}
in case this makes any difference:
Name                           Value
----                           -----
PSVersion                      6.2.3
PSEdition                      Core
GitCommitId                    6.2.3
OS                             Darwin 19.0.0 Darwin Kernel Version 19.0.0: Thu Oct 17 16:17:15 PDT 2019; root:xnu-6153.41.3~29/RELEASE_X86_64
Platform                       Unix
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

【问题讨论】:

    标签: powershell powershell-6.0


    【解决方案1】:

    看起来您的两个数组包含具有各种属性的相似对象。 当您执行此操作时:

    foreach ($record in $tc_records) {
        if($RelationshipEvents_array.entity1Id -eq $record.entity1Id -and $RelationshipEvents_array.entity2Id -eq $record.entity2Id)
    ...
    

    您实际上是在将一个包含所有 entity1Id 属性的数组(通过从 $RelationshipEvents_array 数组中的每个对象中获取该名称的属性来计算)与当前 $recordentity1Id 属性进行比较目的。

    除非我误解了您的问题,否则考虑到不同的对象类型,这不太可能评估为 true。

    当进行这样的比较时,我通常会做如下的事情来获得匹配:

    if($RelationshipEvents_array.entity1Id -contains $record.entity1Id)
    ...
    

    但是,由于您尝试匹配两个属性,因此最简单的方法可能是:

    为您在第二个 foreach 循环中检查的每条记录遍历数组

    foreach ($record in $tc_records) {
        foreach ($event in $RelationshipEvents_array) {
            if ($record.entity1Id -eq $event.entity1Id -and $record.entity2Id -eq $event.entity2Id)
    { # Do matchy stuff
    ...
    

    【讨论】:

    • 这就是我想知道的。如果我对不同的集合执行两个独立的计算。问题是,在我的场景中,他们确实评估为 true
    • 我有一个类似的嵌套循环,但是有一个嵌套的 if.. 尝试你的方法,希望摆脱嵌套的 if。
    • 我意识到,因为我正在寻找丢失的事件,如果我进行嵌套循环,我可以在第一个属性上获得部分匹配,并且永远不会在第二个属性上找到部分匹配的值。所以我必须同时测试这两个属性。
    • 抱歉,您能澄清一下您在哪里进行部分匹配吗?我不确定我是否理解。我打算添加另一种方法来使用索引和 for 循环同时检查两个属性,但它有点令人费解,所以我避免了它,但如果确实有必要,它可能是要走的路。
    • 我试试 :) 所以,我们得到消息,每条消息都有一对,两条消息相互映射:Message1 id1 -> message2 id2 & message 2 id1 -> message 1身份证2。跟我到现在?现在所有这些消息都被另一个系统提取并复制了。因此,系统 1 中的一对和系统 2 中的一对。我的目标是跨 2 个系统在两对中找到丢失的消息。是主要发送者丢弃消息,还是两个系统之间的复制过程,(或者甚至我们的日志系统只是没有报告所有结果)
    【解决方案2】:

    您确实有 compare object cmdlet 可以为您进行数组比较,并有很多选项可以输出数组之间不匹配的对象。

    $a1=@(1,2,3,4,5)
    $b1=@(1,2,3,4,5,6)
    
    Compare-Object -ReferenceObject $a1 -DifferenceObject $b1
    

    不过,要回答您的问题,-and 只是评估一个单独的第二个函数,该函数也必须等于 true 才能评估语句。

    if (true){#runs}
    if (false){#no runs}
    if (true -and true){#runs}
    if (true -and false){#no runs}
    if (false -and true){#no runs}
    

    您似乎在一个单独的数组上使用-eq,没有示例数据很难准确判断,但您应该能够通过简单地执行$RelationshipEvents_array.entity1Id -eq $record.entity1Id 并检查它是否返回真或假来测试您的逻辑。期待它会。如果$RelationshipEvents_array 是一个数组,您可能想要使用-contains

    【讨论】:

    • 这是一个具有多个属性的复杂对象,afaik 比较对象仅适用于字符串。
    • 我的 cmdlet 示例显示它在 int 上工作,而 powershell 自己的 cmdlet 示例显示如何在多属性对象上使用它,例如 get-process 返回的对象。无论如何,我的答案的后半部分有帮助吗?如果您仔细查看this answer,您会发现在数组上使用-eq 不会返回真或假,而是返回匹配的结果数组。
    • 我再看看。简单的示例按预期返回,但是当我加载完整的 1000 个对象时,一些结果作为误报返回。所以我不确定是什么原因造成的。所有的对象都被规范化了
    • 这种方法行不通。此示例仅适用于单值字符串,每个 if 对象都有许多值,PS 示例仅评估一个属性。这很容易:)
    猜你喜欢
    • 2021-12-15
    • 2019-02-04
    • 1970-01-01
    • 1970-01-01
    • 2022-09-23
    • 2022-09-22
    • 1970-01-01
    • 1970-01-01
    • 2021-01-13
    相关资源
    最近更新 更多