Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Powershell Only Add to Array if it doesn't exist

In PowerShell v2, I'm trying to add only unique values to an array. I've tried using an if statement that says, roughly, If (-not $Array -contains 'SomeValue'), then add the value, but this only ever works the first time. I've put a simple code snippet that shows what I'm doing that doesn't work and what I've done as a workaround that does work. Can someone please let me know where my issue is?

Clear-Host
$Words = @('Hello', 'World', 'Hello')

# This will not work
$IncorrectArray = @()
ForEach ($Word in $Words)
{
    If (-not $IncorrectArray -contains $Word)
    {
        $IncorrectArray += $Word
    }
}

Write-Host ('IncorrectArray Count: ' + $IncorrectArray.Length)

# This works as expected
$CorrectArray = @()
ForEach ($Word in $Words)
{
    If ($CorrectArray -contains $Word)
    {
    }
    Else
    {
        $CorrectArray += $Word
    }
}

Write-Host ('CorrectArray Count: ' + $CorrectArray.Length)

The Result of the first method is an array containing only one value: "Hello". The second Method contains two values: "Hello" & "World". Any help is greatly appreciated.

like image 277
Llaslo Avatar asked Apr 22 '13 17:04

Llaslo


People also ask

How do you check if a value is present in an array PowerShell?

Check Elements of an Array of String in PowerShell The “Contains()” method is utilized for checking if a particular string exists as an array element.

What is @() in PowerShell?

What is @() in PowerShell Script? In PowerShell, the array subexpression operator “@()” is used to create an array. To do that, the array sub-expression operator takes the statements within the parentheses and produces the array of objects depending upon the statements specified in it.

Are PowerShell arrays zero based?

Array IndexWindows PowerShell arrays are zero-based, so to refer to the first element of the array $var3 (“element zero”), you would write $var3 [0].


1 Answers

The first time around, you evaluate -not against an empty array, which returns true, which evaluates to: ($true -contains 'AnyNonEmptyString') which is true, so it adds to the array. The second time around, you evaluate -not against a non-empty array, which returns false, which evaluates to: ($false -contains 'AnyNonEmptyString') which is false, so it doesn't add to the array.

Try breaking your conditions down to see the problem:

$IncorrectArray = @()
$x = (-not $IncorrectArray) # Returns true
Write-Host "X is $x"
$x -contains 'hello' # Returns true

then add an element to the array:

$IncorrectArray += 'hello'
$x = (-not $IncorrectArray) # Returns false
    Write-Host "X is $x"
$x -contains 'hello' # Returns false

See the problem? Your current syntax does not express the logic you desire.

You can use the notcontains operator:

Clear-Host
$Words = @('Hello', 'World', 'Hello')

# This will work
$IncorrectArray = @()
ForEach ($Word in $Words)
{
  If ($IncorrectArray -notcontains $Word)
  {
    $IncorrectArray += $Word
  }
}
like image 121
dugas Avatar answered Sep 21 '22 09:09

dugas