I've got 2 arrays:
$array1 = ('1','2','7','9') $array2 = ('7','9','1','2')
These collections are dynamically changed and I need to add the values from the first array to second. I need to create a condition if.... and check... if these arrays are equals - do nothing.
But, if the first array has new value for example it becomes $array1 = ('1','2','7','9', '6') and second array doesn't have such value
then I need to add this '6' new value to the second array...so the second array will become $array2 = ('7','9','1','2', '6')... please help to achieve it.
Please note that values in 2 arrays could be in different order it doesn't matter, the goal is to have the same values inside 2 arrays.
CodePudding user response:
Merge the two and sort out non-unique values:
$array2 = @($array1;$array2) |Sort-Object -Unique
For large arrays you may want to add all items from both arrays to a HashSet instead - it'll only store distinct values, so the resulting set will correspond to the new value of $array2
:
$set = [System.Collections.Generic.HashSet[psobject]]::new()
$array1 |% { [void]$set.Add($_) }
$array2 |% { [void]$set.Add($_) }
$array2 = @($set)
CodePudding user response:
If you want to retain the order in $array2
and append those elements (in order) from $array1
that aren't yet in $array2
, you can use Compare-Object
:
$array1 = '1','2','7','9','6'
$array2 = '7','9','1','2'
$array2 =
(Compare-Object -PassThru $array1 $array2 | Where-Object SideIndicator -eq '<=')
Note: Compare-Object
, like PowerShell in general, is case-insensitive by default; add -CaseSensitive
if needed.
CodePudding user response:
You can use IsSupersetOf
and UnionWith
from HashSet<T>
:
$array1 = [string[]] ('1','2','7','9','new value')
$array2 = [System.Collections.Generic.HashSet[string]] ('7','9','1','2')
if(-not $array2.IsSupersetOf($array1)) {
$array2.UnionWith($array1)
}
$array2
In case you need to have an actual array back you can cast [object[]]
or [string[]]
back depending on your need:
[string[]] $array2
Worth mentioning that hashsets are case sensitive by default, in case you need a case-insensitive hashset you can instantiate it using a case-insensitive comparer:
$array2 = [System.Collections.Generic.HashSet[string]]::new(
[string[]]('7','9','1','2'),
[System.StringComparer]::OrdinalIgnoreCase
)
CodePudding user response:
You could build on top of this solution, by creating a function.
This code block lists array 1 and array 2
It uses the -notcontains
cmdlet to check if the elements in array are in array2 and if not, then appends the element in array 2.
$array = @('1','2','7','9', '15')
$array2 = @('1','2','7','9')
Write-Output "$array `n"
Write-Output "$array2 `n"
$array | ForEach-Object {
if ($array2 -notcontains $_) {
$array2 = $_
}
}
Write-Output "$array2"
Hope this helps!