Sign in to follow this  
Followers 0
Hobbyist

Compare Two 2D Arrays

16 posts in this topic

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

 

Share this post


Link to post
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.

Share this post


Link to post
Share on other sites

Thanks for the reply.

Your suggestion does not get me to where I am trying to go.  It seems it should be possible to use a value in one array to determine if a row in another array is deleted. 

Share this post


Link to post
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

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

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

see post #14 were i get better

 

Edited by iamtheky
1 person likes this

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

Share this post


Link to post
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)

 

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

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

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

Edited by iamtheky

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

Share this post


Link to post
Share on other sites

@iamtheky

Thank you for taking time to explain that section to me. Now I know how to apply it in the future.

Hobbyist

Share this post


Link to post
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

Share this post


Link to post
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.

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

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

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

Share this post


Link to post
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.

Share this post


Link to post
Share on other sites

#14 ·  Posted (edited)

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
1 person likes this

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

Share this post


Link to post
Share on other sites

@iamtheky

Hey, that seems to work the magic, for either col comparing.  It seems more straight forward to me of all the others.  

Many thanks for being sooooo patient with the likes of me.

 

Share this post


Link to post
Share on other sites

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


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

Share this post


Link to post
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
Sign in to follow this  
Followers 0