Search code examples
arrayspowershellobjectcomparison

Is there a simple implementation to test whether all elements of an array are exactly the same?


I need to determine whether all elements of an array are exactly the same. I'd like this to play nice with all data-types as well, Object/String/Int/etc.

Is there an easy way to do this in PowerShell?

function Test-ArrayElementsEqual {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory,Position = 0,ValueFromPipeline)]
        [object]
        $Array,
    )

    $test = $null
    foreach ($item in $Array) {
        if(!$test){
            $test = $item
            continue
        }
        if($test -ne $item){
            return $false
        }
    }
    return $true
}

This is what I have now, but I have a feeling it's a broken implementation, and that there is something more elegant.

Any help would be great.

Edit:


I put together a pretty good utility function for this since last posting. It supports objects, arrays, all numerical data-types, XML, etc.

Here's the code:

https://github.com/visusys/VSYSUtility/blob/main/Public/Test-ObjectContentsAreIdentical.ps1


Solution

  • As in my comment, for simple comparisons you can use what Lee_Dailey proposed in his comment only adding a type comparison which can be accomplished by the use of .GetType() method.

    This function will return $true if all elements are of the same type and same value and will return the index and expected value / type of the first element that is not of the same type or does not have the same value.

    function Test-ArrayElementsEqual {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory)]
        $InputObject
    )
        begin
        {
            $refVal = $InputObject[0]
            $refType = $refVal.GetType()
            $index = 0
        }
    
        process
        {
            foreach($element in $InputObject)
            {
                if($element -isnot $refType)
                {
                    "Different Type at Position $index. Expected Type was {0}." -f $refType.FullName
                    return
                }
                if($element -ne $refVal)
                {
                    "Different Value at Position $index. Expected Value was $refVal."
                    return
                }
    
                $index++
            }
    
            $true
        }
    }
    

    Test Examples

    $arr1 = 123, 123, '123'
    $arr2 = 123, 345, 123
    $arr3 = 'test', 'test', 'test'
    

    Results

    PS /> Test-ArrayElementsEqual $arr1
    Different Type at Position 2. Expected Type was System.Int32.
    
    PS /> Test-ArrayElementsEqual $arr2
    Different Value at Position 1. Expected Value was 123.
    
    PS /> Test-ArrayElementsEqual $arr3
    True
    

    If you're looking for a way of comparing if different objects are the same you might find useful information on the answers of this question: Prevent adding pscustomobject to array if already exists