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!
