Jump to content

Compare Two 2D Arrays


Hobbyist
 Share

Recommended Posts

I am having difficulty in getting the attached script to work.

Compare first Array to second, using a common column (column 1). If there is a match, delete the row in first array.  I also have a line in the comparison to catch a single entry ( "E") and if it exists in first array, delete it as well.

In this example the expected result is to have the first array displayed showing only "Dog" and "Frog".

I think I understood to start reading from the end of the array , moving to its beginning.

Any way I am doing something very wrong, but don't see what it is. Any help and support would be appreciated.

Hobbyist.

#include <Array.au3>


Local $aArray[6][3] = [[1, "Dog", "1111"], [2, "Ant", "2222"], [3, "Frog", "3333"], [4, "Duck", "4444"], [5, "E", "5555"], [6, "Tree", "6666"]]

    _ArrayDisplay($aArray)  ;initial

Local $aArrayTwo[3][2] =[[2,"Ant"], [4,"Duck"],[6,"Tree"]]

 _ArrayDisplay($aArrayTwo) ;comparison array


For $iI = UBound($aArray) - 1 To 0 Step -1
        For $j = UBound($aArrayTwo) - 1 To 0 Step -1
            If $aArray[$iI][1] = "E" Then _ArrayDelete($aArray, $iI)
            If $aArray[$iI][1] = $aArrayTwo[$j][1] Then _ArrayDelete($aArray, $iI)
        Next
    Next

    _ArrayDisplay($aArray) ;after comparison

 

Link to comment
Share on other sites

You are deleting rows from an array that your are iterating, that is potentially going to get awkward...

Here I have just removed the entries, as a working example. You could make a copy of the original array and modify that without encountering this problem.

#include <Array.au3>


Local $aArray[6][3] = [[1, "Dog", "1111"], [2, "Ant", "2222"], [3, "Frog", "3333"], [4, "Duck", "4444"], [5, "E", "5555"], [6, "Tree", "6666"]]

_ArrayDisplay($aArray)  ;initial

Local $aArrayTwo[3][2] =[[2,"Ant"], [4,"Duck"],[6,"Tree"]]

_ArrayDisplay($aArrayTwo) ;comparison array

For $iI = UBound($aArray) -1 To 0 Step -1
  For $j = UBound($aArrayTwo) -1 To 0 Step -1
    If $aArray[$iI][1] = $aArrayTwo[$j][1] Then
      $aArray[$iI][1] = ""
    EndIf
  Next
Next

_ArrayDisplay($aArray) ;after comparison

 

Problem solving step 1: Write a simple, self-contained, running, replicator of your problem.

Link to comment
Share on other sites

Going off your suggestion, I can get to the desired result, but assigning blanks (updated script) and then deleting those rows with blanks or the "E".

This seems like a long way to do this instead of deleting while comparing, but then again I am new at this.

#include <Array.au3>


Local $aArray[6][3] = [[1, "Dog", "1111"], [2, "Ant", "2222"], [3, "Frog", "3333"], [4, "Duck", "4444"], [5, "E", "5555"], [6, "Tree", "6666"]]

    _ArrayDisplay($aArray)  ;initial

Local $aArrayTwo[3][2] =[[2,"Ant"], [4,"Duck"],[6,"Tree"]]

 _ArrayDisplay($aArrayTwo) ;comparison array


For $iI =  UBound($aArray) - 1 To 0 Step -1

            For $j = UBound($aArraytwo) - 1 To 0 Step -1
                ;If $aArray[$iI][1] = "E" Then _ArrayDelete($aArray, $iI)
                If $aArray[$iI][1] = $aArrayTwo[$j][1] Then ;_ArrayDelete($aArray, $iI)
    $aArray[$iI][1] = ""
    EndIf
    Next

    Next

    _ArrayDisplay($aArray) ;after comparison with assigning blanks


For $iI =  UBound($aArray) - 1 To 0 Step -1
    If $aArray[$iI][1] = "" or $aArray[$iI][1] = "E"   then _ArrayDelete($aArray, $iI)

next
_ArrayDisplay($aArray) ;after deleting blanks and "E"

I put the ArrayDisplays lines in just to see the progress at this point.

If there is a shorter way of doing this I am willing to learn it.

Thanks.

Hobbyist

Link to comment
Share on other sites

Hobbyist,

Not a fan of the "blank cell" thing either...another approach...

#include <Array.au3>

Local $aArray1[6][3] = [[1, "Dog", "1111"], [2, "Ant", "2222"], [3, "Frog", "3333"], [4, "Duck", "4444"], [5, "E", "5555"], [6, "Tree", "6666"]]
Local $aArray2[3][2] = [[2, "Ant"], [4, "Duck"], [6, "Tree"]]

; result array
Local $aArray3[UBound($aArray1)][3], $idx = 0, $hit = False

For $i = 0 To UBound($aArray1) - 1

    If $aArray1[$i][1] = "E" Then ContinueLoop

    $hit = False

    For $j = 0 To UBound($aArray2) - 1
        If $aArray1[$i][1] = $aArray2[$j][1] Then $hit = True
    Next

    If Not $hit Then
        $aArray3[$idx][0] = $aArray1[$i][0]
        $aArray3[$idx][1] = $aArray1[$i][1]
        $aArray3[$idx][2] = $aArray1[$i][2]
        $idx += 1
    EndIf

Next

; resize result array to number of occupied cells
ReDim $aArray3[$idx][3]

_ArrayDisplay($aArray3)

kylomas

Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Link to comment
Share on other sites

#initial garbage that spawned other garbage and a garbage explanation by myself

see post #14 were i get better

 

Edited by iamtheky

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Link to comment
Share on other sites

@kylomas

@iamtheky

Thanks for the solutions.  I prefer the solution of iamtheky as it does not add an additional array to deal with.

As to iamtheyky's solution I deleted the condition of comparing the column "0" as that column was just numbered by me and it does not mean it would be the same in the other array. So column 1 is just the column to compare.

I also am not sure as to what  " If $j > 0 Then $i -= 1" does in the script, but see it as one difference from my OP. I also note the difference in the location of the line dealing with the "E" in my OP.

Any help on clarifying that would be appreciated.

Thanks again, you folks are great.

Hobbyist

Local $aArray1[6][3] = [[1, "Dog", "1111"], [2, "Ant", "2222"], [3, "Frog", "3333"], [4, "Duck", "4444"], [5, "E", "5555"], [6, "Tree", "6666"]]
Local $aArray2[3][2] = [[12, "Ant"], [74, "Duck"], [56, "Tree"]]

For $i = UBound($aArray1) - 1 To 0 step -1

    For $j = UBound($aArray2) - 1 to 0 step - 1
        If  $aArray1[$i][1] = $aArray2[$j][1] Then
        _ArrayDelete($aArray1 , $i)
        If $j > 0 Then $i -= 1
        EndIf
    Next

  If $aArray1[$i][1] = "E" Then _ArrayDelete($aArray1 , $i)

Next

_ArrayDisplay($aArray1)

 

Link to comment
Share on other sites

<insert bunch of garbage that would confuse even future me>

again, post #14 I quit my bullshit, promise.

Edited by iamtheky

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Link to comment
Share on other sites

Hobbyist,

Quote

  I prefer the solution of iamtheky as it does not add an additional array to deal with.

Glad you got it sorted.  You know where to go if you need further advice, good luck!

kylomas

Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Link to comment
Share on other sites

@iamtheky

I was toying around with the script and found the following, but not sure as to the ""why":

#include <Array.au3>

Local $aArray1[6][3] = [[1, "Dog", "1111"], [2, "Ant", "2222"], [3, "Frog", "3333"], [4, "Duck", "4444"], [5, "E", "5555"], [ 6, "Tree", "6666"]]
Local $aArray2[3][2] = [[2, "Ant"], [14, "Duck"],[ 1,"Tree"]]

_ArrayDisplay($aArray1,"Initial Array")

For $i = UBound($aArray1) - 1 To 0 step -1

    For $j = UBound($aArray2) - 1 to 0 step - 1
        If  $aArray1[$i][0] = $aArray2[$j][0] Then
        _ArrayDelete($aArray1 , $i)
        If $j > 0 Then $i -= 1
        EndIf
    Next

  If $aArray1[$i][1] = "E" Then _ArrayDelete($aArray1 , $i)

Next

_ArrayDisplay($aArray1)

I changed the array comparison to Col "0" for array1 & array2.  And in array2 changed one of the elements in Col "0" to be "1".  See [1,"Tree"].  This produces ==> Variable subscript badly formatted  for line - If  $aArray1[$i][0] = $aArray2[$j][0] Then.

Just thinking what if I was to search a different column or the elements were arranged differently.  Totally newbie question.

Thanks.

Link to comment
Share on other sites

i think my last one had multiple issues, this one might be a bit more safe

#garbage - see post #14 for better

 

Edited by iamtheky

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Link to comment
Share on other sites

@iamtheky

Thanks again.  So should this work for using either Col 0 or Col 1 depending upon what is defined in

If  $aArray1[$i][0] = $aArray2[$j][0]  or  If  $aArray1[$i][1] = $aArray2[$j][1]??  I thought just changing the If statement to reflect Col choice should work.  It seems the counter is influenced by the col choice.

Link to comment
Share on other sites

3rd time is the charm?

Think I was just making it too retardedly hard trying to be all mathy about it 

#include <Array.au3>

Local $aArray1[6][3] = [[1, "Dog", "1111"], [2, "Ant", "2222"], [3, "Frog", "3333"], [4, "Duck", "4444"], [5, "E", "5555"], [ 6, "Tree", "6666"]]
Local $aArray2[3][2] = [[2, "Ant"], [14, "Duck"],[ 1,"Tree"]]



For $i = UBound($aArray1) - 1 To 0 step -1


    For $j = UBound($aArray2) - 1 to 0 step - 1
        If  $aArray1[$i][1] = $aArray2[$j][1] OR $aArray1[$i][1] = "E" Then
           _ArrayDelete($aArray1 , $i)
           exitloop
        EndIf
    Next


Next

_ArrayDisplay($aArray1)

 

edit: reduced 

Edited by iamtheky

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Link to comment
Share on other sites

Likewise, circuitous routes are not always tolerated, but they are the only routes i know.

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...