Reputation: 3
I have two arrays in a PowerShell script
Array1 - Each object is separated by semi-colon. Object value in the array has Email and Name separated by pipe. The array is retrieved from search API using PnP PowerShell from a SharePoint list.
$searchAPIData = @("[email protected]|Bill";"[email protected]|Paul";"[email protected]|mike";"[email protected]|Mark";"[email protected]|Sam")
Array 2 - Fetches data from a standalone list. Each object is separated by semi-colon. But the Object value in the array has Email and User ID.
$existingDataInList = @("[email protected]|3";"[email protected]|2";"[email protected]|5";"[email protected]|4")
Back Ground - For each email, I am using yammer API to fetch User ID. So instead of making multiple API calls, If I filter for specific items, the API calls can be reduced. I compare based on emails. If the emails are same in both the arrays, then I don't need to call API/ or perform any operations.
If emails are different in both the arrays, then I need to update the data back to the SharePoint list only for items that are present in Array1 and not in Array 2. And a reverse case where items present in array2 and not in array 1 should be removed.
In the above example,
-- I need to filter/extract "[email protected]|mike"
and "[email protected]|Sam"
from Array1. So only 2 API calls are made.
-- I need to remove "[email protected]|5"
from Array2.
I tried using Where , -NotContains $_
or -Contains $_
and is not giving me desired results. Same for Where-Object.
Any inputs are much appreciated. Thanks in advance.
Upvotes: 0
Views: 271
Reputation: 24091
Since the elements to be matched are of different format, consider building hash tables and using the mathcing part as the hash key. Like so,
$searchAPIData = @("[email protected]|Bill";"[email protected]|Paul";"[email protected]|mike";"[email protected]|Mark";"[email protected]|Sam")
$ht1 = @{}
# Split content into two elements, use 1st as key, 2nd as value
$searchAPIData | % { $s = $_.split('|'); $ht1.add($s[0], $s[1]) }
$existingDataInList = @("[email protected]|3";"[email protected]|2";"[email protected]|5";"[email protected]|4")
$ht2 = @{}
$existingDataInList | % { $s = $_.split('|'); $ht2.add($s[0], $s[1]) }
So, what good does this do? Let's see the hashtable contents.
PS /> $ht1
Name Value
---- -----
[email protected] Bill
[email protected] Paul
[email protected] mike
[email protected] Mark
[email protected] Sam
PS /> $ht2
Name Value
---- -----
[email protected] 5
[email protected] 3
[email protected] 2
[email protected] 4
PS />
Note that now the emails (or UPNs quite likely) are in same format. The rest of the data is set in each hashtable key's value for further usage.
Now, let's compare the hashtables. Get an enumerator for hashtable and use it to look for entity on the other hashtable based on hash key. Like so,
foreach($e in $ht1.GetEnumerator()) {
if(-not $ht2.containskey($e.name)) {
write-output $("Didn't find {0} {1} from list" -f $e.name, $e.value)
}
}
Didn't find [email protected] mike from list
Didn't find [email protected] Sam from list
foreach($e in $ht2.GetEnumerator()) {
if(-not $ht1.containskey($e.name)) {
write-output $("Didn't find {0} {1} from list" -f $e.name, $e.value)
}
}
Didn't find [email protected] 5 from list
Upvotes: 0