Compare multidimensional arrays

I've got a problem with multidimensional arrays. I need to compare two multidimensional arrays as follows:

$array1
number      word

$array2
number      word

If "number" from $array1 matches any "number" in $array2, check if corresponding "word" from $array1 also matches "word" in $array2.
Also accept wildcards "*" for "word" in @array1, which should match any "word" in $array2.

Write out all non-matches to a third array, $array3.
The arrays are very different in size. $array1 will hold at most 50 entries. $array2 will probably contain hundreds or thousands.
I'm not very experienced with multidimensional arrays and can't figure out how to loop and match.

Bonus points to the one who figures out what I'm trying to achieve with this. :-)

Thanks in advance! 

  

May 21st, 2015 2:13am

Hint at how you will need to do this.

$array1 | ?{$array2 -contains $_[0] }

I recommend against using arrays for this type of thing.  Use a hash.

$hash=@{1='One';2='Two',3='Three' ...etc }

Free Windows Admin Tool Kit Click here and download it now
May 21st, 2015 5:54am

Try this, it might be what you want:

 

$array1 = @(

            new-object PSObject -prop @{ number=1; word="Ome*"}

            new-object PSObject -prop @{ number=2; word="*+-"}

            new-object PSObject -prop @{ number=3; word="Gamma"}

          )

 

$array2 = @(

            new-object PSObject -prop @{ number=1; word="Omega"}

            new-object PSObject -prop @{ number=2; word="Beta"}

            new-object PSObject -prop @{ number=3; word="Gamma+-"}

            new-object PSObject -prop @{ number=4; word="Omega"}

            new-object PSObject -prop @{ number=5; word="Teta"}

            new-object PSObject -prop @{ number=2; word="Bet"}

            new-object PSObject -prop @{ number=2; word="Beta+-"}

            new-object PSObject -prop @{ number=5; word="Beta"}

          )

 

# Get All Matches

$allmatches = $array1 | % {

                    $item = $_;

                    $array2 | ? { $_ -like $($item) };

                }

 

 

# Get All Non-Matches

$array3 = $array2 | ? { $allmatches -notcontains $_ };

 

# Display Non-Matches

$array3 

May 21st, 2015 8:02am

My point was to not use arrays.

$hash1=@{
     1='One'
     2='Two'
     3='Three'
}

To find a number we just do this:

if($v=$hash[1]){$v}else{#doesn't exist}

Now we can just look up the value directly.

Free Windows Admin Tool Kit Click here and download it now
May 21st, 2015 8:11am

How to test an array:

$a=1,2,3,4,5,6,7

$al=[collections.arraylist]$a

PS >$al.Exists(3)
True
PS >$al.Exists(33)
False

May 21st, 2015 8:18am

Simple example of a converter:

$nums=@{
   1='one'
   2='two'
   3='three'
   4='four'
   5='five'
   6='six'
   7='seven'
   8='eight'
   9='nine'
   0='zed'
}

# get the number
$x='03562391'
$x.ToCharArray()|%{Write-Host $nums[[int]"$_"]' ' -NoNewline}

Free Windows Admin Tool Kit Click here and download it now
May 21st, 2015 8:38am

If you want to (and can) compare HashTable<Key,Value> instead of Array<PSCustomObject> as JRV recommends. 

IMPORTANT: With hashtable you cannot have any duplicate for the key (Which means here the "number")

 

$hashtable1 = @{

        "*"="Ome*"

        2="*+-"

        3="Gamma"

        4="Epsilon"

        5="Teta"

}

 

$hashtable2 = @{

        1="Omega"

        2="Beta"

        3="Gamma+-"

        4="Omega"

        5="Teta"

        6="Alpha"

        7="Beta"

        10="Beta"

} 

 

# Get All Matches

$allmatches = $hashtable1.GetEnumerator() | % {

                $item = $_;

                $hashtable2.GetEnumerator() | ? { $_.name -like $($item.name) -and $_.value -like $($item.value)};

            } 

 

# Get All Non-Matches

$hashtable3 = $hashtable2.GetEnumerator() | ? { $allmatches -notcontains $_ };

 

# Display Non-Matches 

$hashtable3 | FT -AutoSize

May 23rd, 2015 8:56am

If you want to (and can) compare HashTable<Key,Value> instead of Array<PSCustomObject> as JRV recommends. 

IMPORTANT: With hashtable you cannot have any duplicate for the key (Which means here the "number")

 

$hashtable1 = @{

        "*"="Ome*"

        2="*+-"

        3="Gamma"

        4="Epsilon"

        5="Teta"

}

 

$hashtable2 = @{

        1="Omega"

        2="Beta"

        3="Gamma+-"

        4="Omega"

        5="Teta"

        6="Alpha"

        7="Beta"

        10="Beta"

} 

 

# Get All Matches

$allmatches = $hashtable1.GetEnumerator() | % {

                $item = $_;

                $hashtable2.GetEnumerator() | ? { $_.name -like $($item.name) -and $_.value -like $($item.value)};

            } 

 

# Get All Non-Matches

$hashtable3 = $hashtable2.GetEnumerator() | ? { $allmatches -notcontains $_ };

 

# Display Non-Matches 

$hashtable3 | FT -AutoSize

Free Windows Admin Tool Kit Click here and download it now
May 23rd, 2015 8:58am

If you want to (and can) compare HashTable<Key,Value> instead of Array<PSCustomObject> as JRV recommends. 

IMPORTANT: With hashtable you cannot have any duplicate for the key (Which means here the "number")

 

$hashtable1 = @{

        "*"="Ome*"

        2="*+-"

        3="Gamma"

        4="Epsilon"

        5="Teta"

}

 

$hashtable2 = @{

        1="Omega"

        2="Beta"

        3="Gamma+-"

        4="Omega"

        5="Teta"

        6="Alpha"

        7="Beta"

        10="Beta"

} 

 

# Get All Matches

$allmatches = $hashtable1.GetEnumerator() | % {

                $item = $_;

                $hashtable2.GetEnumerator() | ? { $_.name -like $($item.name) -and $_.value -like $($item.value)};

            } 

 

# Get All Non-Matches

$hashtable3 = $hashtable2.GetEnumerator() | ? { $allmatches -notcontains $_ };

 

# Display Non-Matches 

$hashtable3 | FT -AutoSize

May 23rd, 2015 12:55pm

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics