Jump to content

order like Excel does


 Share

Recommended Posts

Hello to all,

try to make file dupes deleter based on crc32.

my program return this :

442A0A98 = 5.Spots.Party.WiiWare.wad
5FF1B7F5 = 35 - Groovin' Blocks (NA).wad
A3C797E2 = 49 - Strong Bad's Cool Game for Attractive People - Episode 3- Baddest of the Bands (NA).wad
B71F1D80 = 5 - Pop (NA).wad
442A0A98 = 5 Spots Party WiiWare.wad

as you can note first row and last have same CRC (442A0A98)

I search the way to make order in rows based on first colum (CRC)

to obtain this:

5FF1B7F5 = 35 - Groovin' Blocks (NA).wad
A3C797E2 = 49 - Strong Bad's Cool Game for Attractive People - Episode 3- Baddest of the Bands (NA).wad
B71F1D80 = 5 - Pop (NA).wad
442A0A98 = 5.Spots.Party.WiiWare.wad
442A0A98 = 5 Spots Party WiiWare.wad

Any idea for function to use ?

Thank you,

m.

Link to comment
Share on other sites

Know func for 1d array, some problem to code for posted text ...

Some time ago i write this, i'm not so sure that text after split [=]

don't influence result:

;1. Read file
$sData = FileRead("test.txt")

;2. Create 2D array, where $a2[$i][0] = value from selected column in Data, $a2[$i][1] = index (to refer to after sorting)
$a = _DSV_ColumnToArray($sData, 1, "=")
Dim $a2[UBound($a)][2]
For $i = 0 To UBound($a)-1
    $a2[$i][0] = $a[$i]
    $a2[$i][1] = $i+1 ;1-based index, to work with StringSplit later
Next

;3. Sort the array
_ArraySortClib($a2, 0)

;4. Make array of lines from Data
$aData = StringSplit(StringStripCR($sData), @LF)

;5. Write lines from array into new file, using index
$sData = $aData[$a2[0][1]]
For $i = 1 To UBound($a2)-1
    $sData &= @CRLF & $aData[$a2[$i][1]]
Next
FileWrite("sorted.txt", stringreplace($sData, "'", ""))


;   _DSV_ColumnToArray()
;   Extracts a column from delimiter separated values file to AutoIt array
Func _DSV_ColumnToArray(Byref $sData, $iColumn, $sDelim)
    Return StringRegExp($sData, "(?U)(?:\A|\n)(?:\V*" & $sDelim & "){" & $iColumn-1 & "}(\V*)(?:" & $sDelim & "|\v|\z)", 3)
EndFunc


;#
;   _ArraySortClib() v3, by Siao
;         Sort 1D/2D array using qsort() from C runtime library (msvcrt.dll, shipped with Windows since Win98 at least)
;   Parameters:
;         $Array - the array to be sorted, ByRef
;         $iMode - sort mode, can be one of the following:
;               0 = numerical, using double precision float compare
;               1 = string compare, case insensitive (default)
;               2 = string compare, case sensitive
;         $fDescend - sort direction. True = descending, False = ascending (default)
;         $iStart - index of starting element (default 0 = $array[0])
;         $iEnd - index of ending element (default 0 = Ubound($array)-1)
;         $iColumn - index of column to sort by (default 0 = first column)
;         $iWidth - max string length of array element to compare (ignored for now)
;   Return values:
;         -1 = dll error
;         0 = sort impossible because
;               @error 0 = nothing to sort
;               @error 1 = invalid array
;               @error 2 = invalid param
;         1 = success
;#
Func _ArraySortClib(ByRef $Array, $iMode = 1, $fDescend = False, $iStart = 0, $iEnd = 0, $iColumn = 0, $iWidth = 0)
    If @AutoItX64 Then Return SetError(666, 0, 0)
    Local $iArrayDims = UBound($Array, 0)
    If @error Or $iArrayDims > 2 Then Return SetError(1, 0, 0)
    Local $iArraySize = UBound($Array, 1), $iColumnMax = UBound($Array, 2)
    If $iArraySize < 2 Then Return 0
    If $iEnd < 1 Or $iEnd > $iArraySize - 1 Then $iEnd = $iArraySize - 1
    If ($iEnd - $iStart < 2) Then Return SetError(2, 0, 0)
    If $iArrayDims = 2 Then
        If ($iColumnMax - $iColumn < 0) Then Return SetError(2, 0, 0)
    EndIf
    If $iWidth < 0 Then Return SetError(2, 0, 0)
    $iWidth = 8
    Local $tSource, $tIndex, $i, $j, $iCount = $iEnd - $iStart + 1, $fNumeric, $fCase, $aRet, $hMsvcrt, $sStrCmp, $tFloatCmp, $pCmp, $tCmpWrap
    Switch $iMode
        Case 0
            $fNumeric = True
        Case 1
            $fCase = False
        Case 2
            $fCase = True
        Case Else
            Return SetError(2, 0, 0)
    EndSwitch
   ;; initialize compare proc
    If $fNumeric Then
        $tFloatCmp = DllStructCreate('byte[36]')
        DllStructSetData($tFloatCmp, 1, '0x8B4C24048B542408DD01DC1ADFE0F6C440750D80E441740433C048C333C040C333C0C3')
        $pCmp = DllStructGetPtr($tFloatCmp)
    Else
        $sStrCmp = "_strcmpi";case insensitive
        If $fCase Then $sStrCmp = "strcmp";case sensitive
        $aRet = DllCall('kernel32.dll', 'hwnd', 'LoadLibraryA', 'str', 'msvcrt.dll')
        $hMsvcrt = $aRet[0]
        $aRet = DllCall('kernel32.dll', 'ptr', 'GetProcAddress', 'ptr', $hMsvcrt, 'str', $sStrCmp)
        DllCall('kernel32.dll', 'hwnd', 'FreeLibrary', 'hwnd', $hMsvcrt)
        If $aRet[0] = 0 Then Return -1
        $pCmp = $aRet[0]
    EndIf
    $tCmpWrap = DllStructCreate('byte[32]')
    DllStructSetData($tCmpWrap, 1, '0xBA' & Hex(Binary($pCmp), 8) & '8B4424088B4C2404FF30FF31FFD283C408C3')
   ;; write data to memory
    If $fNumeric Then
        $tSource = DllStructCreate('double[' & $iCount & ']')
        If $iArrayDims = 1 Then
            For $i = 1 To $iCount
                DllStructSetData($tSource, 1, $Array[$iStart + $i - 1], $i)
            Next
        Else
            For $i = 1 To $iCount
                DllStructSetData($tSource, 1, $Array[$iStart + $i - 1][$iColumn], $i)
            Next
        EndIf
    Else
        Local $sMem = ""
        If $iArrayDims = 1 Then
            For $i = $iStart To $iEnd
                $sMem &= $Array[$i] & Chr(0);safer: $sMem &= StringLeft($Array[$i],4095) & Chr(0)
            Next
        Else
            For $i = $iStart To $iEnd
                $sMem &= $Array[$i][$iColumn] & Chr(0);safer: $sMem &= StringLeft($Array[$i][$iColumn],4095) & Chr(0)
            Next
        EndIf
        $tSource = DllStructCreate('byte[' & StringLen($sMem) + 1 & ']')
        DllStructSetData($tSource, 1, $sMem)
        $sMem = 0
    EndIf
   ;; index data
    $tIndex = DllStructCreate('int[' & $iCount * 2 & ']')
    Local $tEnumProc = DllStructCreate('byte[64]')
    If $fNumeric Then
        DllStructSetData($tEnumProc, 1, '0x8B7424048B7C24088B4C240C8B442410893789470483C60883C708404975F1C21000')
    Else
        DllStructSetData($tEnumProc, 1, '0x8B7424048B7C24088B4C240C8B542410893789570483C7088A064684C075F9424975EDC21000')
    EndIf
    DllCall('user32.dll', 'uint', 'CallWindowProc', 'ptr', DllStructGetPtr($tEnumProc), 'ptr', DllStructGetPtr($tSource), 'ptr', DllStructGetPtr($tIndex), 'int', $iCount, 'int', $iStart)
   ;; sort
    DllCall('msvcrt.dll', 'none:cdecl', 'qsort', 'ptr', DllStructGetPtr($tIndex), 'int', $iCount, 'int', $iWidth, 'ptr', DllStructGetPtr($tCmpWrap))
   ;; read back the result
    Local $aTmp = $Array, $iRef
    If $iArrayDims = 1 Then; 1D
        If $fDescend Then
            For $i = 0 To $iCount - 1
                $iRef = DllStructGetData($tIndex, 1, $i * 2 + 2)
                $Array[$iEnd - $i] = $aTmp[$iRef]
            Next
        Else; ascending
            For $i = $iStart To $iEnd
                $iRef = DllStructGetData($tIndex, 1, ($i - $iStart) * 2 + 2)
                $Array[$i] = $aTmp[$iRef]
            Next
        EndIf
    Else; 2D
        If $fDescend Then
            For $i = 0 To $iCount - 1
                $iRef = DllStructGetData($tIndex, 1, $i * 2 + 2)
                For $j = 0 To $iColumnMax - 1
                    $Array[$iEnd - $i][$j] = $aTmp[$iRef][$j]
                Next
            Next
        Else; ascending
            For $i = $iStart To $iEnd
                $iRef = DllStructGetData($tIndex, 1, ($i - $iStart) * 2 + 2)
                For $j = 0 To $iColumnMax - 1
                    $Array[$i][$j] = $aTmp[$iRef][$j]
                Next
            Next
        EndIf
    EndIf
    Return 1
EndFunc  ;==>_ArraySortClib

so want to sort only for first column (CRC),

m.

Edited by myspacee
Link to comment
Share on other sites

...so want to sort only for first column (CRC)

I don't understand why you think that's so hard:
#include <Array.au3>

; 1D version
Dim $a1[5] = ["442A0A98 = 5.Spots.Party.WiiWare.wad", _
    "5FF1B7F5 = 35 - Groovin' Blocks (NA).wad", _
    "A3C797E2 = 49 - Strong Bad's Cool Game for Attractive People - Episode 3- Baddest of the Bands (NA).wad", _
    "B71F1D80 = 5 - Pop (NA).wad", _
    "442A0A98 = 5 Spots Party WiiWare.wad"]
_ArraySort($a1)
_ArrayDisplay($a1, "1D Test")

; 2D version
Dim $a2[5][2] = [["442A0A98", "5.Spots.Party.WiiWare.wad"], _
    ["5FF1B7F5", "35 - Groovin' Blocks (NA).wad"], _
    ["A3C797E2", "49 - Strong Bad's Cool Game for Attractive People - Episode 3- Baddest of the Bands (NA).wad"], _
    ["B71F1D80", "5 - Pop (NA).wad"], _
    ["442A0A98", "5 Spots Party WiiWare.wad"]]
_ArraySort($a2)
_ArrayDisplay($a2, "2D Test")

:)

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

so for given file i can use :

#include <file.au3>
#include <Array.au3>

Dim $aRecords
dim $avArray[1]

If Not _FileReadToArray("test.txt",$aRecords) Then
   MsgBox(4096,"Error", " Error reading log to Array     error:" & @error)
   Exit
EndIf

For $x = 1 to $aRecords[0]
    _ArrayAdd($avArray, $aRecords[$x])
Next

_ArraySort($avArray, 0, 0, 0, 0)
_ArrayDisplay($avArray, "$avArray AFTER _ArrayAdd()")



$file = FileOpen("final.txt", 2)
FileWrite($file, StringReplace(_ArrayToString($avArray), "|", @CRLF))
FileClose($file)

this working perfectly for my case (think most cases).

Now ask if is possible to delete dupe rows in a text file ?

m.

Link to comment
Share on other sites

Now ask if is possible to delete dupe rows in a text file ?

Dog ate your help file AND your search button?! :)

You already have _ArrayUnique() and there are 2D versions posted, or would be easy to create.

:)

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
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...