0

I am looking for missing events between two arrays: $tc_records & $RelationshipEvents_array. Both arrays should have the same two entries.

An entry for A->B and reverse B->A. When I'm evaluating RelationshipEvents with -and statement, does one (same) event gets evaluated, or each side of the -and loads the array and evaluates is independently.

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
mr.buttons
  • 685
  • 1
  • 9
  • 18

2 Answers2

1

It looks like your two arrays hold similar objects with various properties. When you perform this:

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

You're actually comparing an array holding all the entity1Id properties (calculated by getting the property of that name from each of the objects in the $RelationshipEvents_array array) with the entity1Id property of the current $record object.

This is unlikely to ever evaluate to true given the different object types unless I've misunderstood your question.

What I would normally do when making a comparison like this is something like the following to get a match:

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

However, since you're trying to match two properties the simplest way might be to:

Iterate through the array for each record you check in a second foreach loop

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
...
  • That's what I was wondering. If I was performing two independent calculations against separate collections. Problem is, in my scenario they DO evaluate to true – mr.buttons Dec 11 '19 at 06:25
  • I had a similar nested loop, but with a nested `if`.. gonna try your approach, hopefully get rid of the nested if. – mr.buttons Dec 11 '19 at 06:26
  • I realized that because I'm looking for missing events, if I do nested loop, I can get partial match on the first property, and will never find values where partial match is on the 2nd property. So I have to do it by testing both properties at the same time. – mr.buttons Dec 11 '19 at 07:30
  • Sorry can you clarify where you're doing partial matches? I'm not sure I understand. I was going to add another way to check both properties at the same time using indices and a for loop but it was a bit convoluted so I avoided it but if that's truly necessary it might be the way to go. – Freddy Grande Dec 12 '19 at 07:49
  • I'll try :) So, we get messages, and each message has a pair, and the two messages are mapped to each other: Message1 id1 -> message2 id2 & message 2 id1 -> message 1 id2. With me so far? Now all of these messages are picked off by another system and duplicated. So a pair in system 1 and a pair in system 2. My goal is to find missing messages in the two pairs, across 2 systems. Is the main sender dropping messages, or the duplication process between two systems, (or perhaps even our logging system just not reporting all results) – mr.buttons Dec 13 '19 at 05:17
0

You do have the compare object cmdlet to do array comparisons for you with quite a few options to output non-matching objects between the arrays.

$a1=@(1,2,3,4,5)
$b1=@(1,2,3,4,5,6)

Compare-Object -ReferenceObject $a1 -DifferenceObject $b1

To answer your question though, -and is a just evaluating a separate 2nd function that must also equal true for the statement to be evaluated.

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

You seem to be using -eq on a separate array, hard to tell exactly with no example data but you should be able to test your logic by simply doing $RelationshipEvents_array.entity1Id -eq $record.entity1Id and checking if it returns true or false as you are expecting it would. If $RelationshipEvents_array is an array you probably want to use -contains

Nick
  • 1,783
  • 1
  • 15
  • 18
  • it's a complex object with multiple properties, afaik compare object only works on strings. – mr.buttons Dec 10 '19 at 02:08
  • My example of the cmdlet shows it working on ints and powershells own examples of the cmdlet show how to use it on multi-property objects such as ones returned by `get-process`. Regardless, does the 2nd half of my answer help? If you have a close look at [this answer](https://stackoverflow.com/a/9598371/5487553) you will see that using `-eq` on an array doesn't return true or false but rather array of results that matched. – Nick Dec 10 '19 at 02:20
  • I'll take a look again. Simple examples come back as expected, but when I load full collection 1000s of objects, some results come back as false positives. So i'm not sure what's causing it. All of the objects are normalized – mr.buttons Dec 10 '19 at 18:49
  • This approach wont work. This example only works with single value strings, every if object has many values, PS examples evaluate only one property. That's easy :) – mr.buttons Dec 11 '19 at 07:33