Finding an item of one array that matches a certain string of an item in another array

T Crha 396 Reputation points
2024-02-04T23:33:03.53+00:00

Hello everyone, I humbly ask for help with one powershell issue that I cant solve. Its basically described in the title - I have two arrays containing a lot of items, and I need to find an item from array 1 that matches a certain string of characters in array 2. So far I tried something like this:

[array]$arr1 = 'charlie','echo','bravo','lima','zulu','alpha'
[array]$arr2 = 'eagle', 'horse', 'cat', 'goat', 'dog', 'charlie'
$arr1 | Where-Object {$arr2 -contains 'charlie'}

But this will only return all items from array1:

PS C:\Users\user\folder> $arr1 | Where-Object {$arr2 -contains 'charlie'}
charlie
echo
bravo
lima
zulu
alpha

Anyone has a clue how to do it so the result displayed on screen is just the one/ones matching the certain string, so, in other words, only items from array 1 that match the string in array 2? Many thanks for any hints, Tomas

Windows for business | Windows Server | User experience | PowerShell
0 comments No comments
{count} votes

Accepted answer
  1. Rich Matheisen 47,901 Reputation points
    2024-02-06T19:45:12.25+00:00

    If I understood your most recent explanation of the problem, what you really want to do is to match the GUID portion of the array elements (which is pretty much the same as my last answer, but using a different part of the elements):

    $arr1 = "Sample st. 13-13, A City, 123456 State - Something and something else_ba6e1a5d-a8ef-480a-924f-cf61fea2813b",
            "Sample st. 13-13, A City, 123456 State - Something and something else_02483af8-21f4-4f97-be65-0b159b825318"
    
    $arr2 = "Sample st. 13_13, A City, 123456 State - Something and something else_02483af8-21f4-4f97-be65-0b159b825318",
            "Sample st. 13_13, A City, 123456 State - Something and something else_6f4624ce-ad27-462f-8dbb-d8930298bd30"
    
    $hash2 = @{}
    foreach ($a2 in $arr2){
        if ($a2 -match '(\w{8}-\w{4}-\w{4}-\w{4}-\w{12})'){
            $hash2[($matches[1])] = $a2
        }
    }
    
    # if $arr1 contains a match in $arr2 emit the value from $arr1
    foreach ($a1 in $arr1){
        if ($a1 -match '(\w{8}-\w{4}-\w{4}-\w{4}-\w{12})'){
            if ( $hash2.ContainsKey( $matches[1] )){
                    $a1
            }
        }
    }
    

2 additional answers

Sort by: Most helpful
  1. Rich Matheisen 47,901 Reputation points
    2024-02-05T00:24:17.4866667+00:00

    Something like this will work:

    [array]$arr1 = 'charlie','echo','bravo','lima','zulu','alpha'
    [array]$arr2 = 'eagle', 'horse', 'cat', 'goat', 'dog', 'charlie'
    
    $arr2 |
        ForEach-Object{
            $arr1 -eq $_
        }
    

  2. Rich Matheisen 47,901 Reputation points
    2024-02-05T16:19:03.3133333+00:00

    If the only differences are the presence of the characters "-" or "_", then this will find them:

    [array]$arr1 = 'abc_charlie123','echo','bravo','lima','zulu','alpha','abc_charlie456','abc_charlie789' 
    [array]$arr2 = 'abc-charlie456', 'eagle', 'horse', 'cat', 'goat', 'dog', 'abc-charlie123','abc-charlie789'
    
    # if $arr1 contains a match in $arr2 emit the value from $arr1
    foreach ($a1 in $arr1){
        foreach ($a2 in $arr2){
            if ( ($a1 -replace "[_-]","") -eq ($a2 -replace "[_-]","") ){
                $a1
            }
        }
    }
    

    NOTE: That presents the absolute worst case for execution speed!

    This code requires more memory but loops only once over $arr1 and $arr2, and it should run much faster. If the two data sets are in files, then creating the two arrays isn't necessary, which makes this much more preferable:

    [array]$arr1 = 'abc_charlie123','echo','bravo','lima','zulu','alpha','abc_charlie456','abc_charlie789' 
    [array]$arr2 = 'abc-charlie456', 'eagle', 'horse', 'cat', 'goat', 'dog', 'abc-charlie123','abc-charlie789'
    
    $hash2 = @{}
    foreach ($a2 in $arr2){
        $hash2[($a2 -replace "[_-]","")] = $a2
    }
    
    # if $arr1 contains a match in $arr2 emit the value from $arr1
    foreach ($a1 in $arr1){
        $x = $a1 -replace "[_-]",""
        if ( $hash2.ContainsKey( $x )){
                $hash2.$x
        }
    }
    

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.