Jump to content

Help with _ArrayUnique - ScreenShot included.


 Share

Recommended Posts

It's my code so far, i used _ArrayUnique but i think it remove some of my values.

#include <Array.au3>
Dim $aArray[4][5] = [["IR.CHAMPiON", 14, 3955, 2505, 251],["IR.CHAMPiON", 14, 3955, 2505, 251],["Sorena70", 29, 17275, 8985, 899],["otot_otot", 30, 7175, 20885, 2089]]
_ArrayDisplay($aArray, "GoDLiKe.eXp EXP Log", -1, 0, "", "|", "ID|Username|Level|Current EXP|Remaining EXP|Remaining Time")

Take a look at the attachment please.

It's all about removing the duplicated values in Array based on Username.

Edited by D4RKON3
Link to comment
Share on other sites

Unfortunately _Arrayunique only works with 1-dimensional arrays.

According to the help file: "Returns the Unique Elements of a 1-dimensional array."

You could try the written by BrewManNH for a working _ArrayUnique.

Edited by water

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

Unfortunately _Arrayunique only works with 1-dimensional arrays.

According to the help file: "Returns the Unique Elements of a 1-dimensional array."

Yes, i just noticed after posting here.

You could try the written by BrewManNH for a working _ArrayUnique.

Thanks i will take a look on that. BTW any working code can be great.

Link to comment
Share on other sites

kind of clunky but seemingly functional for the example given:

#include <Array.au3>
Dim $aArray[4][5] = [["IR.CHAMPiON", 14, 3955, 2505, 251],["IR.CHAMPiON", 14, 3955, 2505, 251],["Sorena70", 29, 17275, 8985, 899],["otot_otot", 30, 7175, 20885, 2089]]


_ArrayDisplay($aArray, "BEFORE", -1, 0, "", "|", "ID|Username|Level|Current EXP|Remaining EXP|Remaining Time")

for $i = ubound($aArray) - 1 to 1 step -1
    if $aArray[$i][0] = $aArray[$i -1][0] Then
        if $aArray[$i][1] = $aArray[$i - 1][1] And $aArray[$i][2] = $aArray[$i - 1][2] And $aArray[$i][3] = $aArray[$i - 1][3] And $aArray[$i][4] = $aArray[$i - 1][4] Then _ArrayDelete($aArray , $i)
    EndIf
Next

_ArrayDisplay($aArray, "AFTER", -1, 0, "", "|", "ID|Username|Level|Current EXP|Remaining EXP|Remaining Time")

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

Link to comment
Share on other sites

I've come to the same result but only checking 1 element of each row:

#include <Array.au3>
Dim $aArray[4][5] = [["IR.CHAMPiON", 14, 3955, 2505, 251],["IR.CHAMPiON", 14, 3955, 2505, 251],["Sorena70", 29, 17275, 8985, 899],["otot_otot", 30, 7175, 20885, 2089]]
_ArraySort($aArray)
For $iIndex = UBound($aArray, 1)-1 To 1 Step -1
    If $aArray[$iIndex][0] = $aArray[$iIndex-1][0] Then _ArrayDelete($aArray, $iIndex)
Next
_ArrayDisplay($aArray, "GoDLiKe.eXp EXP Log", -1, 0, "", "|", "ID|Username|Level|Current EXP|Remaining EXP|Remaining Time")

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

Here is an example of a _ArrayUnique2D() function that uses only a 2D input array and returns a unique 2D array.

This function has the options:-

  • To choose which column or columns to search for a row's uniqueness;
  • Specify a row index at which to start scanning the input array, and;
  • Select case sensitive searching.
#include <array.au3>
; Modified from http://www.autoitscript.com/forum/index.php?showtopic=102993&view=findpost&p=730315

Local $user_list[5][2] = [["larry", "usa"],["bob", "canada"],["mary", "usa"],["bob", "canada"],["bob", "mexico"]]
_ArrayDisplay($user_list, "before")
; Have person from each country
Local $aUnique = _ArrayUnique2D($user_list, "1", 0, 0) ; Column 1, Base 0, Case-insensitive.
_ArrayDisplay($aUnique, "after Unique Countries")

Local $aAnotherArray[6][4] = [["Row", "Zero"],[1, 2, 4, "a"],[1, "b", 5, 2],[1, 2, 7, 8],[1, 2, 3, "a"],[6, "B", 3, 2]] ; Another test array
; Starting at row 1, delete the rows that have duplicate, case-sensitive, first and third column elements.
_ArrayDisplay($aAnotherArray, "before row[4] is deleted (col1 & col3 match row[1])")
Local $aUnique = _ArrayUnique2D($aAnotherArray, "1,3", 1, 1) ; Checking column 1 & 3, Base 1, Case-sensitive.
_ArrayDisplay($aUnique, "after Base 1, Case-sensitive, col1 & col3")
; Note :-
; [1, 2, 4, "a"] <- First row
; [1, 2, 3, "a"] <- Forth row
;  ~~~^~~~~~~^~~ <- Col1 And Col3 match. So, entire forth row is deleted for uniqueness sake.


; #FUNCTION# ====================================================================================================================
; Name...........: _ArrayUnique2D
; Description ...: Returns a 2-dimensional array consisting of rows having one or more unique specified columns.
; Syntax.........: _ArrayUnique($aArray[, $sCols = ""[, $iBase = 0[, $iCase = 0]]])
; Parameters ....: $aArray - Input array (2D only)
;                 $sCols  - [optional] The column/s of each row to check for duplicates. (Default "", for all columns
;                                                          of each row.)(Columns have base zero) e.g. "0,2" means if the data in col0, and col2 on a
;                            row matches the data in col0, and col2 on another row, then the entire other row is deleted.
;                 $iBase  - [optional] Row index at which to start scanning the input array
;                 $iCase  - [optional] Flag to indicate if the operations should be case sensitive.
;                           0 = not case sensitive, using the user's locale (default)
;                           1 = case sensitive
;                           2 = not case sensitive, using a basic/faster comparison
; Return values .: Success - Returns a 2-dimensional array containing only the unique row elements of the input array.
;                Failure  - Returns 0 and sets @error:
;                               | 1 - Only 2 dimensional arrays are supported.
;                               | 2 - $sCols is out of range
;                               | 3 - $iBase is out of range
; Author ........: Malkey
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: Yes
; ===============================================================================================================================
Func _ArrayUnique2D(ByRef $aArrayIn, $sCols = "", $iBase = 0, $iCase = 0)
    If UBound($aArrayIn, 0) <> 2 Then Return SetError(1, 0, 0) ; Not 2D array    ;

    If ($iBase > UBound($aArrayIn, 2)) Or ($iBase < 0) Then Return SetError(3, 0, 0) ; checks the given base is valid

    Local $aTemp[UBound($aArrayIn)][UBound($aArrayIn, 2)], $aColsel, $sUnique = "<#>", $sStr = "<#>", $iCount = 0

    If $iBase > 0 Then
        For $i = 0 To $iBase
            For $j = 0 To UBound($aArrayIn, 2) - 1
                $aTemp[$i][$j] = $aArrayIn[$i][$j]
            Next
        Next
        $iCount = $iBase
    EndIf

    If $sCols == "" Then
        Local $aColsel[UBound($aArrayIn, 2)]
        For $i = 0 To UBound($aArrayIn, 2) - 1
            $aColsel[$i] = $i
        Next
    ElseIf StringRegExpReplace($sCols, "", "") <> "" Then
        $aColsel = StringRegExp(StringStripWS($sCols, 8), "(\d+),?", 3)
    Else
        Return SetError(2, 0, 0) ; $sCols parameter failure
    EndIf

    For $r = $iBase To UBound($aArrayIn, 1) - 1

        ;Create string consisting of each specified column/s for each row, $r.
        For $c = 0 To UBound($aColsel) - 1
            If $aColsel[$c] > UBound($aArrayIn, 2) or $aColsel[$c] < 0 Then Return SetError(2, 0, 0) ; $sCols parameter failure
            $sStr &= $aArrayIn[$r][$aColsel[$c]] & "<#>"
        Next

        ; Check if string of each specified column/s already exists in the $sUnique string variable.
        If StringInStr($sUnique, "<#>" & $sStr, $iCase) = 0 Then
            For $x = 0 To UBound($aArrayIn, 2) - 1
                $aTemp[$iCount][$x] = $aArrayIn[$r][$x]
            Next
            $sUnique &= $sStr
            $iCount += 1
        EndIf
        $sStr = ""
    Next

    ReDim $aTemp[$iCount][UBound($aArrayIn, 2)]
    Return SetError(0, 0, $aTemp)
EndFunc   ;==>_ArrayUnique2D
Link to comment
Share on other sites

@Malkey:

When I use instead

Local $user_list[5][2] = [["larry", "usa"],["boby", "canada"],["mary", "usa"],["bob", "canada"],["bob", "mexico"]]

no items should be unique but it will delete the bob canada entry nevertheless.

Br,

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

The function _ArrayUnique that's in the Array.au3 UDF file DOES handle 2D arrays already, the help file information about it is, sadly, incorrect as to what it does or how to use it. It returns a 1D array containing the elements of one of the dimensions of a 2D or 1D array with all of the duplicates removed.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

@Malkey:

When I use instead

Local $user_list[5][2] = [["larry", "usa"],["boby", "canada"],["mary", "usa"],["bob", "canada"],["bob", "mexico"]]

no items should be unique but it will delete the bob canada entry nevertheless.

Br,

UEZ

@UEZ

You may not have grasped the meaning and usefulness of the "$sCols" parameter in my example of post #9.

Using the array,

Local $user_list[5][2] = [["larry", "usa"],["boby", "canada"],["mary", "usa"],["bob", "canada"],["bob", "mexico"]]

My example uses the command line,

Local $aUnique = _ArrayUnique2D($user_list, "1", 0, 0) ; Column 1, Base 0, Case-insensitive.

The "$sCols" parameter is "1". This means that the uniqueness of the array is dependent on the contents of the second column, that is column 1.

This means row[2] is out because row[2]'s col1 matches the col1 of row[0], "usa".

And row[3] is out because its second column has "canada" which is the same as the col1 of the second row, row[1].

If instead "" is used as "$sCols" parameter as in

Local $aUnique = _ArrayUnique2D($user_list, "", 0, 0) ;  All columns , Base 0, Case-insensitive

This means all the columns are used to determine a line's uniqueness. And, in this case, no lines (nothing) of the input array will be deleted.

Malkey.

Link to comment
Share on other sites

Guys i need your helps again.

It's my code so far:

#include <Array.au3>
Dim $Array[15][3]=[["Sorena70",29,1500],["Sorena70",29,1550],["Sorena70",29,1600],["otot_otot",30,7000],["otot_otot",30,7100],["otot_otot",30,7200],["NinJa",52,17800],["NinJa",52,17900],["NinJa",53,0],["GG_WarSong",9,2400],["GG_WarSong",9,2500],["GG_WarSong",10,100],["IR.CHAMPiON",13,5950],["IR.CHAMPiON",14,0],["IR.CHAMPiON",14,50]]
_ArraySort($Array, 1, 0, 0, 0)
 
;~ For $i = UBound($Array, 1) - 1 To 1 Step -1
;~  If $Array[$i][0] = $Array[$i - 1][0] Then
;~  _ArrayDelete($Array, $i)
;~  EndIf
;~ Next
 
_ArrayDisplay($Array, "EXP Log", -1, 0, "", "|", "ID|Username           |Level|Current EXP  ")

Take a look this:

I can explain it well in English so i made this ScreenShot, i hope you can figure out what i'm trying to do.

Something like: I want 1 of each Username with Higher Level but if the levels are same show the higher Current EXP.

Edited by D4RKON3
Link to comment
Share on other sites

Try this.

#include <Array.au3>

Local $Array[15][3] = [["Sorena70", 29, 1500],["Sorena70", 29, 1550],["Sorena70", 29, 1600], _
        ["otot_otot", 30, 7000],["otot_otot", 30, 7100],["otot_otot", 30, 7200],["NinJa", 52, 17800], _
        ["NinJa", 52, 17900],["NinJa", 53, 0],["GG_WarSong", 9, 2400],["GG_WarSong", 9, 2500], _
        ["GG_WarSong", 10, 100],["IR.CHAMPiON", 13, 5950],["IR.CHAMPiON", 14, 0],["IR.CHAMPiON", 14, 50]]

; Create a 1D array from the given 2D array
Local $Array1D[UBound($Array)], $string = ""
For $r = 0 To UBound($Array) - 1
    $Array1D[$r] = StringRight("aaaaaaaaaaaaaaa" & $Array[$r][0], 15) & StringRight("000" & $Array[$r][1], 3) & _
            StringRight("000000" & $Array[$r][2], 6) & StringRight("00" & $r, 2)
Next

_ArraySort($Array1D, 1) ; Sort the 1D array

; Create a new 2D array from the given 2D array in the order of the sorted 1D array.
Local $Array2D[UBound($Array)][UBound($Array, 2)], $num
For $r = 0 To UBound($Array) - 1
    $num = Number(StringRight($Array1D[$r], 2)) ; Row order of new 2D array
    For $c = 0 To UBound($Array, 2) - 1
        $Array2D[$r][$c] = $Array[$num][$c]
    Next
Next

Local $aUnique = _ArrayUnique2D($Array2D, "0", 0, 0) ; Column 0 (only), Base 0, Case-insensitive.
_ArrayDisplay($aUnique, "Unique Sorted Array")


; #FUNCTION# ====================================================================================================================
; Name...........: _ArrayUnique2D
; Description ...: Returns a 2-dimensional array consisting of rows having one or more unique specified columns.
; Syntax.........: _ArrayUnique($aArray[, $sCols = ""[, $iBase = 0[, $iCase = 0]]])
; Parameters ....: $aArray - Input array (2D only)
;                $sCols  - [optional] The column/s of each row to check for duplicates. (Default "", for all columns
;                                                         of each row.)(Columns have base zero) e.g. "0,2" means if the data in col0, and col2 on a
;                           row matches the data in col0, and col2 on another row, then the entire other row is deleted.
;                $iBase  - [optional] Row index at which to start scanning the input array
;                $iCase  - [optional] Flag to indicate if the operations should be case sensitive.
;                          0 = not case sensitive, using the user's locale (default)
;                          1 = case sensitive
;                          2 = not case sensitive, using a basic/faster comparison
; Return values .: Success - Returns a 2-dimensional array containing only the unique row elements of the input array.
;               Failure  - Returns 0 and sets @error:
;                              | 1 - Only 2 dimensional arrays are supported.
;                              | 2 - $sCols is out of range
;                              | 3 - $iBase is out of range
; Author ........: Malkey
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: Yes
; ===============================================================================================================================
Func _ArrayUnique2D(ByRef $aArrayIn, $sCols = "", $iBase = 0, $iCase = 0)
    If UBound($aArrayIn, 0) <> 2 Then Return SetError(1, 0, 0) ; Not 2D array    ;

    If ($iBase > UBound($aArrayIn, 2)) Or ($iBase < 0) Then Return SetError(3, 0, 0) ; checks the given base is valid

    Local $aTemp[UBound($aArrayIn)][UBound($aArrayIn, 2)], $aColsel, $sUnique = "<#>", $sStr = "<#>", $iCount = 0

    If $iBase > 0 Then
        For $i = 0 To $iBase
            For $j = 0 To UBound($aArrayIn, 2) - 1
                $aTemp[$i][$j] = $aArrayIn[$i][$j]
            Next
        Next
        $iCount = $iBase
    EndIf

    If $sCols == "" Then
        Local $aColsel[UBound($aArrayIn, 2)]
        For $i = 0 To UBound($aArrayIn, 2) - 1
            $aColsel[$i] = $i
        Next
    ElseIf StringRegExpReplace($sCols, "", "") <> "" Then
        $aColsel = StringRegExp(StringStripWS($sCols, 8), "(\d+),?", 3)
    Else
        Return SetError(2, 0, 0) ; $sCols parameter failure
    EndIf

    For $r = $iBase To UBound($aArrayIn, 1) - 1

        ;Create string consisting of each specified column/s for each row, $r.
        For $c = 0 To UBound($aColsel) - 1
            If $aColsel[$c] > UBound($aArrayIn, 2) Or $aColsel[$c] < 0 Then Return SetError(2, 0, 0) ; $sCols parameter failure
            $sStr &= $aArrayIn[$r][$aColsel[$c]] & "<#>"
        Next

        ; Check if string of each specified column/s already exists in the $sUnique string variable.
        If StringInStr($sUnique, "<#>" & $sStr, $iCase) = 0 Then
            For $x = 0 To UBound($aArrayIn, 2) - 1
                $aTemp[$iCount][$x] = $aArrayIn[$r][$x]
            Next
            $sUnique &= $sStr
            $iCount += 1
        EndIf
        $sStr = ""
    Next

    ReDim $aTemp[$iCount][UBound($aArrayIn, 2)]
    Return SetError(0, 0, $aTemp)
EndFunc   ;==>_ArrayUnique2D
Link to comment
Share on other sites

  • 4 months later...

Try this.

Hi Malkey,

thank you for posting the _ArrayUnique2D function. I just have one problem. The func seems to search top down for the first 'unique' value in the column specified and drops every other row afterwards with the same value. I would need this same functionality but bottom up. Could you please assist me as I do not find the spot where the changes have to be made.

Thank you very much and best regards,

phr3n1c

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...