Sign in to follow this  
Followers 0
BugFix

Compare Arrays, Strings; _GetIntersection

8 posts in this topic

#1 ·  Posted (edited)

Hi,

i think, that many scripts exist to compare arrays or strings. In my version i use object "System.Collections.ArrayList", that gives a good performances for great sets.

Test it and form your own opinion.

Explanation you find in function-header.

EDIT 14.10.2008

- now using Default and Opt("GUIDataSeparatorChar") for $Delim

- fixed a bug by using @CRLF as separator

#include <array.au3>
Local $1 = '1,1,2,3,3,3,4,4,5,6,7'
Local $2[10] = ['5','5','5','8','8','9','12','12','3','1']

Local $ret = _GetIntersection($1, $2, 0, ',')
If IsArray($ret) Then _ArrayDisplay($ret)

$ret = _GetIntersection($1, $2, 1, ',')
If IsArray($ret) Then _ArrayDisplay($ret)

;==================================================================================================
; Function Name:   _GetIntersection($Set1, $Set2 [, $GetAll=0 [, $Delim=Default]])
; Description::    Detect from 2 sets
;                  - Intersection (elements are contains in both sets)
;                  - Difference 1 (elements are contains only in $Set1)
;                  - Difference 2 (elements are contains only in $Set2)
; Parameter(s):    $Set1    set 1 (1D-array or delimited string)
;                  $Set2    set 2 (1D-array or delimited string)
;      optional:   $GetAll  0 - only one occurence of every different element are shown (Default)
;                           1 - all elements of differences are shown
;      optional:   $Delim   Delimiter for strings (Default use the separator character set by Opt("GUIDataSeparatorChar") )
; Return Value(s): Succes   2D-array    [i][0]=Intersection
;                                       [i][1]=Difference 1
;                                       [i][2]=Difference 2
;                  Failure  -1  @error  set, that was given as array, is'nt 1D-array
; Note:            Comparison is case-sensitiv! - i.e. Number 9 is different to string '9'!
; Author(s):       BugFix (bugfix@autoit.de)
;==================================================================================================
Func _GetIntersection(ByRef $Set1, ByRef $Set2, $GetAll=0, $Delim=Default)
    Local $o1 = ObjCreate("System.Collections.ArrayList")
    Local $o2 = ObjCreate("System.Collections.ArrayList")
    Local $oUnion = ObjCreate("System.Collections.ArrayList")
    Local $oDiff1 = ObjCreate("System.Collections.ArrayList")
    Local $oDiff2 = ObjCreate("System.Collections.ArrayList")
    Local $tmp, $i
    If $GetAll <> 1 Then $GetAll = 0
    If $Delim = Default Then $Delim = Opt("GUIDataSeparatorChar")
    If Not IsArray($Set1) Then
        If Not StringInStr($Set1, $Delim) Then
            $o1.Add($Set1)
        Else
            $tmp = StringSplit($Set1, $Delim, 1)
            For $i = 1 To UBound($tmp) -1
                $o1.Add($tmp[$i])
            Next
        EndIf
    Else
        If UBound($Set1, 0) > 1 Then Return SetError(1,0,-1)
        For $i = 0 To UBound($Set1) -1
            $o1.Add($Set1[$i])
        Next
    EndIf
    If Not IsArray($Set2) Then
        If Not StringInStr($Set2, $Delim) Then
            $o2.Add($Set2)
        Else
            $tmp = StringSplit($Set2, $Delim, 1)
            For $i = 1 To UBound($tmp) -1
                $o2.Add($tmp[$i])
            Next
        EndIf
    Else
        If UBound($Set2, 0) > 1 Then Return SetError(1,0,-1)
        For $i = 0 To UBound($Set2) -1
            $o2.Add($Set2[$i])
        Next
    EndIf
    For $tmp In $o1
        If $o2.Contains($tmp) And Not $oUnion.Contains($tmp) Then $oUnion.Add($tmp)
    Next
    For $tmp In $o2
        If $o1.Contains($tmp) And Not $oUnion.Contains($tmp) Then $oUnion.Add($tmp)
    Next
    For $tmp In $o1
        If $GetAll Then
            If Not $oUnion.Contains($tmp) Then $oDiff1.Add($tmp)
        Else
            If Not $oUnion.Contains($tmp) And Not $oDiff1.Contains($tmp) Then $oDiff1.Add($tmp)
        EndIf
    Next
    For $tmp In $o2
        If $GetAll Then
            If Not $oUnion.Contains($tmp) Then $oDiff2.Add($tmp)
        Else
            If Not $oUnion.Contains($tmp) And Not $oDiff2.Contains($tmp) Then $oDiff2.Add($tmp)
        EndIf
    Next
    Local $UBound[3] = [$oDiff1.Count,$oDiff2.Count,$oUnion.Count], $max = 1
    For $i = 0 To UBound($UBound) -1
        If $UBound[$i] > $max Then $max = $UBound[$i]
    Next
    Local $aOut[$max][3]
    If $oUnion.Count > 0 Then
        $i = 0
        For $tmp In $oUnion
            $aOut[$i][0] = $tmp
            $i += 1
        Next
    EndIf
    If $oDiff1.Count > 0 Then
        $i = 0
        For $tmp In $oDiff1
            $aOut[$i][1] = $tmp
            $i += 1
        Next
    EndIf
    If $oDiff2.Count > 0 Then
        $i = 0
        For $tmp In $oDiff2
            $aOut[$i][2] = $tmp
            $i += 1
        Next
    EndIf
    Return $aOut
EndFunc  ;==>_GetIntersection

_GetIntersection.au3

Edited by BugFix
2 people like this

Best Regards BugFix  

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

You could change it so $Delim parameter by default will use the separator character set by Opt("GUIDataSeparatorChar").

Line 29:

_GetIntersection(ByRef $Set1, ByRef $Set2, $GetAll=0, $Delim=Default)

Line 37:

If $Delim = Default Then $Delim = Opt("GUIDataSeparatorChar")

Very nice work.

Edited by mrRevoked

Don't bother, It's inside your monitor!------GUISetOnEvent should behave more like HotKeySet()

Share this post


Link to post
Share on other sites

Thanks for your responses.

@mrRevoked

Thats a very good idea. I'll apply your incitation in my solution.


Best Regards BugFix  

Share this post


Link to post
Share on other sites

I know this is an old thread, but it's just been referenced here:

Find differences in Arrays, String; _Diff

I'd suggest replacing 20 lines of code (lines 68-87 inclusive) with the following:

For $tmp In $o1 ; create union and diff1 arrays
        If $o2.Contains($tmp) Then
            If Not $oUnion.Contains($tmp) Then $oUnion.Add($tmp)
        Else
            If $GetAll Or Not $oDiff1.Contains($tmp) Then $oDiff1.Add($tmp)
        EndIf
    Next
    For $tmp In $o2 ; create diff2 array
        If Not $oUnion.Contains($tmp) And ($GetAll Or Not $oDiff2.Contains($tmp)) Then $oDiff2.Add($tmp)
    Next

It trims your 4 loops down to 2 and removes a kazillion calls to the time-consuming ".Contains" method.

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

I'm trying to build a list comparison program based upon this function. But I am having some issues and don't know if its the function or my code? Anyone care to help me sort it out? Its function is simple, paste in 2 lists, and it will show you the items unique to each list and what each list has in common. The issues seem to be it sometimes shows an element that i don't need it to, or it hides and element that needs to be seen.  Try it and you'll see what i mean. I think it has to do with phantom end of line CRLF etc. Thanks for any assistance.

#NoTrayIcon
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=..\Icons\listcompare.ico
#AutoIt3Wrapper_Outfile=..\Program\ListCompare.Exe
#AutoIt3Wrapper_Compression=4
#AutoIt3Wrapper_Run_Tidy=y
#Tidy_Parameters=/tc 3 /reel
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

Opt("GUICloseOnESC", 0) ; Disable ESC to close!

; +----------------------------------------------------------------+
; | Define local and global variables.                             |
; +----------------------------------------------------------------+

#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <array.au3>

#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("List Compare", 462, 648)
GUISetBkColor(0xC0C0C0)
$List1 = GUICtrlCreateEdit("", 16, 48, 200, 265)
GUICtrlSetData(-1, "")
$List2 = GUICtrlCreateEdit("", 248, 48, 200, 265)
GUICtrlSetData(-1, "")
$Name1 = GUICtrlCreateInput("Left", 16, 16, 200, 21)
$Name2 = GUICtrlCreateInput("Right", 248, 16, 200, 21)
$Button1 = GUICtrlCreateButton("Compare", 137, 320, 195, 25)
$Edit1 = GUICtrlCreateEdit("", 15, 375, 129, 257, BitOR($GUI_SS_DEFAULT_EDIT, $ES_READONLY))
GUICtrlSetData(-1, "")
$Edit2 = GUICtrlCreateEdit("", 167, 375, 129, 257, BitOR($GUI_SS_DEFAULT_EDIT, $ES_READONLY))
GUICtrlSetData(-1, "")
$Edit3 = GUICtrlCreateEdit("", 319, 375, 129, 257, BitOR($GUI_SS_DEFAULT_EDIT, $ES_READONLY))
GUICtrlSetData(-1, "")
$Label1 = GUICtrlCreateLabel("", 16, 352, 124, 17)
$Label2 = GUICtrlCreateLabel("Both", 168, 352, 124, 17)
$Label3 = GUICtrlCreateLabel("", 318, 352, 124, 17)
GUICtrlSetData($Label1, GUICtrlRead($Name1) & " Only")
GUICtrlSetData($Label3, GUICtrlRead($Name2) & " Only")
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

While 1
   $nMsg = GUIGetMsg()
   Switch $nMsg
      Case $GUI_EVENT_CLOSE
         Exit
      Case $Button1
         $value1 = StringUpper(GUICtrlRead($List1))
         $value2 = StringUpper(GUICtrlRead($List2))

         $Test1 = StringSplit($value1, @CRLF, $STR_ENTIRESPLIT)
         $Test2 = StringSplit($value2, @CRLF, $STR_ENTIRESPLIT)

         Local $ret = _GetIntersection($Test1, $Test2, 0)

         If IsArray($ret) Then
            ;_ArraySort($ret, 1, 1)

            $ret1 = _ArrayUnique($ret)
            $ret2 = _ArrayUnique($ret, 1)
            $ret3 = _ArrayUnique($ret, 2)

            $ret1 = _ArrayToString($ret1, "|", 1)
            $ret2 = _ArrayToString($ret2, "|", 2)
            $ret3 = _ArrayToString($ret3, "|", 2)

            $ret1 = StringReplace($ret1, "||", "|")
            $ret2 = StringReplace($ret2, "||", "|")
            $ret3 = StringReplace($ret3, "||", "|")

            $ret1 = StringReplace($ret1, "|", @CRLF)
            $ret2 = StringReplace($ret2, "|", @CRLF)
            $ret3 = StringReplace($ret3, "|", @CRLF)

            GUICtrlSetData($Edit1, $ret2)
            GUICtrlSetData($Edit2, $ret1)
            GUICtrlSetData($Edit3, $ret3)

            GUICtrlSetData($Label1, GUICtrlRead($Name1) & " Only")
            GUICtrlSetData($Label3, GUICtrlRead($Name2) & " Only")
         EndIf
   EndSwitch
WEnd

;==================================================================================================
; Function Name:   _GetIntersection($Set1, $Set2 [, $GetAll=0 [, $Delim=Default]])
; Description::    Detect from 2 sets
;                  - Intersection (elements are contains in both sets)
;                  - Difference 1 (elements are contains only in $Set1)
;                  - Difference 2 (elements are contains only in $Set2)
; Parameter(s):    $Set1    set 1 (1D-array or delimited string)
;                  $Set2    set 2 (1D-array or delimited string)
;      optional:   $GetAll  0 - only one occurence of every different element are shown (Default)
;                           1 - all elements of differences are shown
;      optional:   $Delim   Delimiter for strings (Default use the separator character set by Opt("GUIDataSeparatorChar") )
; Return Value(s): Succes   2D-array    [i][0]=Intersection
;                                       [i][1]=Difference 1
;                                       [i][2]=Difference 2
;                  Failure  -1  @error  set, that was given as array, is'nt 1D-array
; Note:            Comparison is case-sensitiv! - i.e. Number 9 is different to string '9'!
; Author(s):       BugFix (bugfix@autoit.de)
;==================================================================================================
Func _GetIntersection(ByRef $Set1, ByRef $Set2, $GetAll = 0, $Delim = Default)
   Local $o1 = ObjCreate("System.Collections.ArrayList")
   Local $o2 = ObjCreate("System.Collections.ArrayList")
   Local $oUnion = ObjCreate("System.Collections.ArrayList")
   Local $oDiff1 = ObjCreate("System.Collections.ArrayList")
   Local $oDiff2 = ObjCreate("System.Collections.ArrayList")
   Local $tmp, $i
   If $GetAll <> 1 Then $GetAll = 0
   If $Delim = Default Then $Delim = Opt("GUIDataSeparatorChar")
   If Not IsArray($Set1) Then
      If Not StringInStr($Set1, $Delim) Then
         $o1.Add($Set1)
      Else
         $tmp = StringSplit($Set1, $Delim, 1)
         For $i = 1 To UBound($tmp) - 1
            $o1.Add($tmp[$i])
         Next
      EndIf
   Else
      If UBound($Set1, 0) > 1 Then Return SetError(1, 0, -1)
      For $i = 0 To UBound($Set1) - 1
         $o1.Add($Set1[$i])
      Next
   EndIf
   If Not IsArray($Set2) Then
      If Not StringInStr($Set2, $Delim) Then
         $o2.Add($Set2)
      Else
         $tmp = StringSplit($Set2, $Delim, 1)
         For $i = 1 To UBound($tmp) - 1
            $o2.Add($tmp[$i])
         Next
      EndIf
   Else
      If UBound($Set2, 0) > 1 Then Return SetError(1, 0, -1)
      For $i = 0 To UBound($Set2) - 1
         $o2.Add($Set2[$i])
      Next
   EndIf
   For $tmp In $o1 ; create union and diff1 arrays
      If $o2.Contains($tmp) Then
         If Not $oUnion.Contains($tmp) Then $oUnion.Add($tmp)
      Else
         If $GetAll Or Not $oDiff1.Contains($tmp) Then $oDiff1.Add($tmp)
      EndIf
   Next
   For $tmp In $o2 ; create diff2 array
      If Not $oUnion.Contains($tmp) And ($GetAll Or Not $oDiff2.Contains($tmp)) Then $oDiff2.Add($tmp)
   Next
   Local $UBound[3] = [$oDiff1.Count, $oDiff2.Count, $oUnion.Count], $max = 1
   For $i = 0 To UBound($UBound) - 1
      If $UBound[$i] > $max Then $max = $UBound[$i]
   Next
   Local $aOut[$max][3]
   If $oUnion.Count > 0 Then
      $i = 0
      For $tmp In $oUnion
         $aOut[$i][0] = $tmp
         $i += 1
      Next
   EndIf
   If $oDiff1.Count > 0 Then
      $i = 0
      For $tmp In $oDiff1
         $aOut[$i][1] = $tmp
         $i += 1
      Next
   EndIf
   If $oDiff2.Count > 0 Then
      $i = 0
      For $tmp In $oDiff2
         $aOut[$i][2] = $tmp
         $i += 1
      Next
   EndIf
   Return $aOut
EndFunc   ;==>_GetIntersection

 

Edited by zone97
minor code change.

 

Spoiler

WinSizer 2.1 (01/04/2017) - Download - [ Windows Layout Manager ]
Folder+Program (12/23/2016) - Download - [ USB Shortcut Creator ]

 

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

@zone97, change this part in your code:

$Test1 = StringSplit($value1, @CRLF, $STR_ENTIRESPLIT)
         $Test2 = StringSplit($value2, @CRLF, $STR_ENTIRESPLIT)

         Local $ret = _GetIntersection($Test1, $Test2, 0)

         If IsArray($ret) Then
            ;_ArraySort($ret, 1, 1)

            $ret1 = _ArrayUnique($ret)
            $ret2 = _ArrayUnique($ret, 1)
            $ret3 = _ArrayUnique($ret, 2)

            $ret1 = _ArrayToString($ret1, "|", 1)
            $ret2 = _ArrayToString($ret2, "|", 2)
            $ret3 = _ArrayToString($ret3, "|", 2)

with this:

$Test1 = StringSplit($value1, @CRLF, $STR_ENTIRESPLIT + $STR_NOCOUNT)
         $Test2 = StringSplit($value2, @CRLF, $STR_ENTIRESPLIT + $STR_NOCOUNT)

         Local $ret = _GetIntersection($Test1, $Test2, 0)

         If IsArray($ret) Then
            ;_ArraySort($ret, 1, 1)

            $ret1 = _ArrayUnique($ret, 0, 0, 0, 0)
            $ret2 = _ArrayUnique($ret, 1, 0, 0, 0)
            $ret3 = _ArrayUnique($ret, 2, 0, 0, 0)

            $ret1 = _ArrayToString($ret1, "|")
            $ret2 = _ArrayToString($ret2, "|")
            $ret3 = _ArrayToString($ret3, "|")

 

Edited by Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

@ChimpThank you for the help. It seems to be nearly perfect. The only other thing that breaks it (which is really not that important) but would like to understand why.. Is if the list contain only 2 items each it crashes. (id like to catch that in an error message to prevent it from closing.) Here is the updates you suggested and some changes I made.

#NoTrayIcon
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=..\Icons\listcompare.ico
#AutoIt3Wrapper_Outfile=..\Program\ListCompare.exe
#AutoIt3Wrapper_Compression=4
#AutoIt3Wrapper_Run_Tidy=y
#Tidy_Parameters=/tc 3 /reel
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

Opt("GUICloseOnESC", 0) ; Disable ESC to close!

; +----------------------------------------------------------------+
; | Define local and global variables.                             |
; +----------------------------------------------------------------+

#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <array.au3>
#include <WinAPI.au3>

#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("List Compare", 465, 651, -1, -1)
GUISetBkColor(0xC0C0C0)
$List1 = GUICtrlCreateEdit("", 16, 48, 200, 265)
GUICtrlSetData(-1, "")
$List2 = GUICtrlCreateEdit("", 248, 48, 200, 265)
GUICtrlSetData(-1, "")
$Name1 = GUICtrlCreateInput("Left", 16, 16, 200, 21)
$Name2 = GUICtrlCreateInput("Right", 248, 16, 200, 21)
$Button1 = GUICtrlCreateButton("Compare", 15, 320, 203, 25)
$Button2 = GUICtrlCreateButton("Compare Case", 247, 320, 201, 25)
$Edit1 = GUICtrlCreateEdit("", 16, 375, 145, 257, BitOR($GUI_SS_DEFAULT_EDIT, $ES_READONLY))
GUICtrlSetData(-1, "")
$Edit2 = GUICtrlCreateEdit("", 160, 375, 145, 257, BitOR($GUI_SS_DEFAULT_EDIT, $ES_READONLY))
GUICtrlSetData(-1, "")
$Edit3 = GUICtrlCreateEdit("", 304, 375, 145, 257, BitOR($GUI_SS_DEFAULT_EDIT, $ES_READONLY))
GUICtrlSetData(-1, "")
$Label1 = GUICtrlCreateLabel("", 16, 352, 140, 17)
$Label2 = GUICtrlCreateLabel("Both", 160, 352, 140, 17)
$Label3 = GUICtrlCreateLabel("", 302, 352, 140, 17)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

GUICtrlSetData($Label1, GUICtrlRead($Name1) & " Only")
GUICtrlSetData($Label3, GUICtrlRead($Name2) & " Only")

While 1
   $nMsg = GUIGetMsg()
   If WinActive("List Compare") Then
      HotKeySet("^a", "_selectall")
   Else
      HotKeySet("^a")
   EndIf
   Switch $nMsg
      Case $GUI_EVENT_CLOSE
         Exit
      Case $Button1
         $CheckCase = 0
         _DoCompare()
      Case $Button2
         $CheckCase = 1
         _DoCompare()
   EndSwitch
WEnd

Func _DoCompare()
   $Value1 = GUICtrlRead($List1)
   $Value2 = GUICtrlRead($List2)

   $Value1 = StringRegExpReplace($Value1, '\R', '|')
   $Value2 = StringRegExpReplace($Value2, '\R', '|')

   Do ; -- Remove all blank and white space entries
      $Value1 = StringReplace($Value1, "||", "|")
      $Value2 = StringReplace($Value2, "||", "|")

      $Value1 = StringReplace($Value1, " ", "")
      $Value2 = StringReplace($Value2, " ", "")

      $CheckV1 = StringInStr($Value1 & $Value2, "||")
      $CheckV2 = StringInStr($Value1 & $Value2, " ")
   Until $CheckV1 = 0 And $CheckV2 = 0

   If StringRight($Value1, 1) = "|" Then $Value1 = StringTrimRight($Value1, 1)
   If StringRight($Value2, 1) = "|" Then $Value2 = StringTrimRight($Value2, 1)

   $cTestV1 = StringSplit(StringUpper($Value1), '|', $STR_ENTIRESPLIT + $STR_NOCOUNT)
   $cTestV2 = StringSplit(StringUpper($Value2), '|', $STR_ENTIRESPLIT + $STR_NOCOUNT)

   $TestV1 = StringSplit($Value1, '|', $STR_ENTIRESPLIT + $STR_NOCOUNT)
   $TestV2 = StringSplit($Value2, '|', $STR_ENTIRESPLIT + $STR_NOCOUNT)

   _ArraySort($TestV1)
   _ArraySort($TestV2)

   $ListV1 = _ArrayToString($TestV1, "|")
   $ListV2 = _ArrayToString($TestV2, "|")

   $Value1 = StringReplace($ListV1, '|', @CRLF)
   $Value2 = StringReplace($ListV2, '|', @CRLF)

   GUICtrlSetData($List1, $Value1)
   GUICtrlSetData($List2, $Value2)

   If $CheckCase = 0 Then $RetV = _GetIntersection($cTestV1, $cTestV2, 0)
   If $CheckCase = 1 Then $RetV = _GetIntersection($TestV1, $TestV2, 0)

   If IsArray($RetV) Then

      $RetV1 = _ArrayUnique($RetV, 0, 0, 0, 0)
      $RetV2 = _ArrayUnique($RetV, 1, 0, 0, 0)
      $RetV3 = _ArrayUnique($RetV, 2, 0, 0, 0)

      $RetV1 = _ArrayToString($RetV1, "|")
      $RetV2 = _ArrayToString($RetV2, "|")
      $RetV3 = _ArrayToString($RetV3, "|")

      $RetV1 = StringReplace($RetV1, "|", @CRLF)
      $RetV2 = StringReplace($RetV2, "|", @CRLF)
      $RetV3 = StringReplace($RetV3, "|", @CRLF)

      GUICtrlSetData($Edit1, $RetV2)
      GUICtrlSetData($Edit2, $RetV1)
      GUICtrlSetData($Edit3, $RetV3)

      GUICtrlSetData($Label1, GUICtrlRead($Name1) & " Only")
      GUICtrlSetData($Label3, GUICtrlRead($Name2) & " Only")
   EndIf
EndFunc   ;==>_DoCompare
;==================================================================================================
; Function Name:   _GetIntersection($Set1, $Set2 [, $GetAll=0 [, $Delim=Default]])
; Description::    Detect from 2 sets
;                  - Intersection (elements are contains in both sets)
;                  - Difference 1 (elements are contains only in $Set1)
;                  - Difference 2 (elements are contains only in $Set2)
; Parameter(s):    $Set1    set 1 (1D-array or delimited string)
;                  $Set2    set 2 (1D-array or delimited string)
;      optional:   $GetAll  0 - only one occurence of every different element are shown (Default)
;                           1 - all elements of differences are shown
;      optional:   $Delim   Delimiter for strings (Default use the separator character set by Opt("GUIDataSeparatorChar") )
; Return Value(s): Succes   2D-array    [i][0]=Intersection
;                                       [i][1]=Difference 1
;                                       [i][2]=Difference 2
;                  Failure  -1  @error  set, that was given as array, is'nt 1D-array
; Note:            Comparison is case-sensitiv! - i.e. Number 9 is different to string '9'!
; Author(s):       BugFix (bugfix@autoit.de)
;==================================================================================================
Func _GetIntersection(ByRef $Set1, ByRef $Set2, $GetAll = 0, $Delim = Default)
   Local $o1 = ObjCreate("System.Collections.ArrayList")
   Local $o2 = ObjCreate("System.Collections.ArrayList")
   Local $oUnion = ObjCreate("System.Collections.ArrayList")
   Local $oDiff1 = ObjCreate("System.Collections.ArrayList")
   Local $oDiff2 = ObjCreate("System.Collections.ArrayList")
   Local $tmp, $i
   If $GetAll <> 1 Then $GetAll = 0
   If $Delim = Default Then $Delim = Opt("GUIDataSeparatorChar")
   If Not IsArray($Set1) Then
      If Not StringInStr($Set1, $Delim) Then
         $o1.Add($Set1)
      Else
         $tmp = StringSplit($Set1, $Delim, 1)
         For $i = 1 To UBound($tmp) - 1
            $o1.Add($tmp[$i])
         Next
      EndIf
   Else
      If UBound($Set1, 0) > 1 Then Return SetError(1, 0, -1)
      For $i = 0 To UBound($Set1) - 1
         $o1.Add($Set1[$i])
      Next
   EndIf
   If Not IsArray($Set2) Then
      If Not StringInStr($Set2, $Delim) Then
         $o2.Add($Set2)
      Else
         $tmp = StringSplit($Set2, $Delim, 1)
         For $i = 1 To UBound($tmp) - 1
            $o2.Add($tmp[$i])
         Next
      EndIf
   Else
      If UBound($Set2, 0) > 1 Then Return SetError(1, 0, -1)
      For $i = 0 To UBound($Set2) - 1
         $o2.Add($Set2[$i])
      Next
   EndIf
   For $tmp In $o1 ; create union and diff1 arrays
      If $o2.Contains($tmp) Then
         If Not $oUnion.Contains($tmp) Then $oUnion.Add($tmp)
      Else
         If $GetAll Or Not $oDiff1.Contains($tmp) Then $oDiff1.Add($tmp)
      EndIf
   Next
   For $tmp In $o2 ; create diff2 array
      If Not $oUnion.Contains($tmp) And ($GetAll Or Not $oDiff2.Contains($tmp)) Then $oDiff2.Add($tmp)
   Next
   Local $UBound[3] = [$oDiff1.Count, $oDiff2.Count, $oUnion.Count], $max = 1
   For $i = 0 To UBound($UBound) - 1
      If $UBound[$i] > $max Then $max = $UBound[$i]
   Next
   Local $aOut[$max][3]
   If $oUnion.Count > 0 Then
      $i = 0
      For $tmp In $oUnion
         $aOut[$i][0] = $tmp
         $i += 1
      Next
   EndIf
   If $oDiff1.Count > 0 Then
      $i = 0
      For $tmp In $oDiff1
         $aOut[$i][1] = $tmp
         $i += 1
      Next
   EndIf
   If $oDiff2.Count > 0 Then
      $i = 0
      For $tmp In $oDiff2
         $aOut[$i][2] = $tmp
         $i += 1
      Next
   EndIf
   Return $aOut
EndFunc   ;==>_GetIntersection

Func _selectall()
   _SendMessage(ControlGetHandle("", "", ""), $EM_SETSEL, 0, -1)
EndFunc   ;==>_selectall

 

Edited by zone97
Update #2, more code changes, added case check.

 

Spoiler

WinSizer 2.1 (01/04/2017) - Download - [ Windows Layout Manager ]
Folder+Program (12/23/2016) - Download - [ USB Shortcut Creator ]

 

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

seems a problem with _ArrayUnique

try to replace this part of your script:

$RetV1 = _ArrayUnique($RetV, 0, 0, 0, 0)
      $RetV2 = _ArrayUnique($RetV, 1, 0, 0, 0)
      $RetV3 = _ArrayUnique($RetV, 2, 0, 0, 0)

      $RetV1 = _ArrayToString($RetV1, "|")
      $RetV2 = _ArrayToString($RetV2, "|")
      $RetV3 = _ArrayToString($RetV3, "|")

with this:

$RetV1 = _ArrayToString($RetV, "|", -1, -1, @CRLF, 0, 0)
         $RetV2 = _ArrayToString($RetV, "|", -1, -1, @CRLF, 1, 1)
         $RetV3 = _ArrayToString($RetV, "|", -1, -1, @CRLF, 2, 2)

p.s.

(just for curiosity) in the following post there was a similar script to achieve the same result...

 

Edited by Chimp
1 person likes this

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

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