简体   繁体   中英

Powershell foreach over two arrays

All, Trying to get this working but have not had any luck with ps.

$a = 
"install.res.1028.dll"
"install.res.1031.dll"
"install.res.1033.dll"
"install.res.1036.dll"
"install.res.1040.dll"
"install.res.1041.dll"
"install.res.1042.dll"
"install.res.2052.dll"

$b = 
"install.res.1041.dll"
"install.res.1042.dll"
"install.res.2052.dll"

I just wish to have a new array with the values that are found in $a and not found in $b, trying to test it out with write-host but no luck. I have tried compare-object but I am unable to pull out just the name. I am a totally noob with ps. Please, any suggestions appreciated.

foreach ($i in $a)
{ foreach-object ($b | where { {$_.name} -ne $i }) { write-host $i}}

Another solution using compare-object as follows:

$c = Compare-Object -ReferenceObject $a -DifferenceObject $b -PassThru

output:

install.res.1028.dll
install.res.1031.dll
install.res.1033.dll
install.res.1036.dll
install.res.1040.dll

CORRECTION:

The above code WILL work for the case where DifferenceObject is guaranteed to be a subset of ReferenceObject. It will FAIL, though, if there are additional objects in DifferenceObject that are not also present in ReferenceObject. The above code returns any objects which are present in EITHER ReferenceObject OR DifferenceObject but NOT in both.

To properly return ONLY objects in ReferenceObject that are not also present in DifferenceObject, the following code is required:

Compare-Object -ReferenceObject $a -DifferenceObject $b | 
    Where-Object { $_.SideIndicator -eq '<=' } | 
    ForEach-Object  { Write-Output $_.InputObject }

The where-object clause ensures only objects that are present in ReferenceObject are passed down the pipeline.

The foreach-object clause forces the output back to a simple array (ref: Converting Custom Object arrays to String arrays in Powershell - thanks Keith)

$c = $a | Where-Object { $b -notcontains $_ }

This should do the job.

Some Explanation

Where-Object 's code block tests each element of the array that's piped into it. The block is supposed to return a boolean value, and if it's true, then the result of the call will contain the item in question.

So for the conditional, we use the -notcontains operator with your second array. $_ refers to the individual item from $a .

This doesn't require an additional or nested loop.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM