Sign in to follow this  
Followers 0
creeping

sorting array

6 posts in this topic

I have a .txt file:

1;2;3;def;5

1;2;3;abc;5

1;2;3;xyz;5

1;2;3;def;5

1;2;3;jkl;5

1;2;3;def;5

I would like to sort this file based on the 4 index (abc,....)

Output example:

1;2;3;abc;5

1;2;3;def;5

1;2;3;def;5

1;2;3;def;5

1;2;3;jkl;5

1;2;3;xyz;5

Any ideas? mainly I just need the logic, not neccessarily code

Share this post


Link to post
Share on other sites



Hi

#include <File.au3>

_FileReadToArray ( $sFilePath, $aArray )

#include <Array.au3>

_ArraySort ( ByRef $a_Array [, $i_Descending [, $i_Base=0 [, $i_Ubound=0 [, $i_Dim=1 [, $i_SortIndex=0 ]]]]] )

_FileWriteFromArray ( $sFilePath, $a_Array [, $i_Base [, $i_UBound ]] )

- See helpfile for parameters

Best, randall

Share this post


Link to post
Share on other sites

I have a .txt file:

1;2;3;def;5

1;2;3;abc;5

1;2;3;xyz;5

1;2;3;def;5

1;2;3;jkl;5

1;2;3;def;5

I would like to sort this file based on the 4 index (abc,....)

Interesting problem, sorting on a field in the middle of the line. Had to take a shot at it:

#include <file.au3>
#include <array.au3>

$InFile = @ScriptDir & "\TestIn.txt"
$Outfile = @ScriptDir & "\TestOut.txt"

Dim $avInput[1] = [0], $avSplit[1] = [0], $avSort[1] = [0], $avOutput[1] = [0]
; Read file to array
If _FileReadToArray($InFile, $avInput) Then
    ; Evaluate each line
    For $n = 1 To $avInput[0]
        $avSplit = StringSplit($avInput[$n], ";")
        If $avSplit[0] > 1 Then
            ; Create a sortable index based on fourth field
            _ArrayAdd($avSort, $avSplit[4] & "||" & $n) ; 'Double pipe' delimits index number
        EndIf
    Next
    $avSort[0] = UBound($avSort) - 1
    
    If $avSort[0] > 0 Then
        ; Sort the index
        _ArraySort($avSort, 0, 1) ; Ascending, start from [1]
        
        ; Use sorted index to copy lines from $avInput to $avOutput
        For $n = 1 To $avSort[0]
            $avSplit = StringSplit($avSort[$n], "||")
            _ArrayAdd($avOutput, $avInput[$avSplit[$avSplit[0]]])
        Next
        $avOutput[0] = UBound($avOutput) - 1
        
        ; Write to output file
        If _FileWriteFromArray($Outfile, $avOutput, 1) Then
            ; Open file to display results
            Run("notepad.exe " & $Outfile)
            Exit
        Else
            MsgBox(16, "Error", "Error writing to file: " & $Outfile) ; write from [1] to end
        EndIf
    Else
        MsgBox(16, "Error", "No valid lines found to sort.")
    EndIf
Else
    MsgBox(16, "Error", "Error reading file: " & $InFile)
EndIf

This could have been a little shorter by using a 2D-array to hold the split fields of all the lines (_ArraySort() works on 2D-arrays), but the logic is clearer in this version.

:)


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

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

Great, thanks guys. This is what I came up with:

1;2;3;def

4;5;6;abc

7;8;9;xyz

10;11;12;def

13;14;15;abc

16;17;18;def

#include <Array.au3>
#include <File.au3>

Global $sFile = 'test.txt'
Global $aFileLineArray = 0, $aEventDump[1][1], $aEventData = 0
Global Const $cDelim = ';'

_FileReadToArray($sFile, $aFileLineArray)
_ArrayDisplay($aFileLineArray, '$aFileLineArray')

ReDim $aEventDump[UBound($aFileLineArray)][4]
Zero2DimArray($aEventDump)
$aEventDump[0][0] = UBound($aFileLineArray) - 1

For $y = 1 to UBound($aEventDump, 1) - 1 Step 1
    $aEventData = StringSplit($aFileLineArray[$y], $cDelim)
    For $x = 0 to UBound($aEventDump, 2) - 1 Step 1
        $aEventDump[$y][$x] = $aEventData[$x + 1]   
    Next
Next

Display2DimArray($aEventDump)
_ArraySort($aEventDump, 0, 1, 0, UBound($aEventDump, 2), 3)
Display2DimArray($aEventDump)

Func Display2DimArray($aArray)
    Local $iNumX = UBound($aArray, 2) - 1
    Local $iNumY = UBound($aArray, 1) - 1
    Local $sArray = '', $sTemp = ''
    
    For $y = 0 To $iNumY Step 1
        $sTemp = ''
        For $x = 0 To $iNumX Step 1
            $sTemp &= $aArray[$y][$x] & @TAB & @TAB
        Next
        $sArray &= $sTemp & @CRLF
    Next
    MsgBox(0, '', $sArray)
EndFunc

Func Zero2DimArray(ByRef $aArray)
    For $y = 0 To UBound($aArray) - 1 Step 1
        For $x = 0 To UBound($aArray, 2) - 1 Step 1
            $aArray[$y][$x] = 0 
        Next
    Next
EndFunc
Edited by creeping

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