# Someone have a best way to sort an array 2D by the first line?

## Recommended Posts

Hi Forum!

I write this little code, to order an array by the first line, this main's point, the first line (or line 0) have any label name, each col means a label's data.

The others is a data.

Like this (example):

+--+--+

|bb|aa|

+--+--+

|22|11|

+--+--+

Then build a array with labels (aa, bb), sort, and change the columns by the sort result:

After sort:

+--+--+

|aa|bb|

+--+--+

|11|22|

+--+--+

Someone have a best way to do this?

```#include <Array.au3>

Local \$arr[][3] = [ _
['cField', 'aField', 'bField'], _
['333', '111', '222'] _
]

_ArrayTec(\$arr)

Func _ArrayTec(ByRef \$arr)
_ArrayDisplay(\$arr, 'before sort')
__ArrayTecSort(\$arr)
_ArrayDisplay(\$arr, 'after sort')
EndFunc   ;==>_ArrayTec

Func __ArrayTecSort(ByRef \$arr)
Local \$col[UBound(\$arr, 2)][3]
For \$ii = 0 To UBound(\$arr, 2) - 1
\$col[\$ii][0] = \$arr[0][\$ii]
\$col[\$ii][1] = \$ii
Next
Local \$old = \$col
_ArraySort(\$old, 1)
For \$ii = 0 To UBound(\$arr, 2) - 1
\$col[\$ii][1] = \$old[\$ii][2]
Next

For \$ii = 0 To UBound(\$arr, 2) - 1
_ArraySwap(\$arr, \$old[\$ii][1], \$old[\$ii][2], True)
Next
EndFunc   ;==>__ArrayTecSort```

Br, Detefon!

Edited by Detefon

Visit my repository

##### Share on other sites

I would transpose the array (switch rows and columns) by using _ArrayTranspose, sort the array with _ArraySort and then transpose the array again.

Never tried it myxself so I don't know how fast this approach is.

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2020-09-05 - Version 1.5.1.1) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2020-06-27 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (NEW 2020-06-27 - Version 1.3.2.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
PowerPoint (2017-06-06 - Version 0.0.5.0) - Download - General Help & Support
Excel - Example Scripts - Wiki
Word - Wiki
Task Scheduler (2019-12-03 - Version 1.5.1.0) - Download - General Help & Support - Wiki

Tutorials:
ADO - Wiki, WebDriver - Wiki

##### Share on other sites

@water, I never try _ArrayTranspose, very interesting... I will try, thank you!

Edited by Detefon

Visit my repository

##### Share on other sites

For small arrays does not have diference...
With small arrays, above 50 lines, is notable.

```_ArraySortMethodOne(2,2)= 0.292023906830606
_ArraySortMethodTwo(2,2)= 0.191301020851811
_ArraySortMethodOne(5,2)= 0.232966962893399
_ArraySortMethodTwo(5,2)= 0.315211909358098
_ArraySortMethodOne(10,2)= 0.262676591131748
_ArraySortMethodTwo(10,2)= 0.733320579931943
_ArraySortMethodOne(50,2)= 0.230793087656447
_ArraySortMethodTwo(50,2)= 13.8305565700307
_ArraySortMethodOne(100,2)= 0.230793087656447
_ArraySortMethodTwo(100,2)= 54.7367292163035
_ArraySortMethodOne(2,5)= 0.613395129360069
_ArraySortMethodTwo(2,5)= 0.491658116090735
_ArraySortMethodOne(5,5)= 0.655785696480641
_ArraySortMethodTwo(5,5)= 0.517382306394671
_ArraySortMethodOne(10,5)= 0.571004562239497
_ArraySortMethodTwo(10,5)= 1.07715517990991
_ArraySortMethodOne(50,5)= 0.474267114195115
_ArraySortMethodTwo(50,5)= 15.1765476542437
_ArraySortMethodOne(100,5)= 0.531512495434862
_ArraySortMethodTwo(100,5)= 56.2569926320122
_ArraySortMethodOne(2,10)= 1.17896500350719
_ArraySortMethodTwo(2,10)= 1.13621212384712
_ArraySortMethodOne(5,10)= 1.30432514217144
_ArraySortMethodTwo(5,10)= 1.34236795881811
_ArraySortMethodOne(10,10)= 1.72098456258732
_ArraySortMethodTwo(10,10)= 1.66627536912402
_ArraySortMethodOne(50,10)= 1.14563224987392
_ArraySortMethodTwo(50,10)= 16.8366637101963
_ArraySortMethodOne(100,10)= 0.989113232813342
_ArraySortMethodTwo(100,10)= 61.129009350562```
```#include <Array.au3>
#include <File.au3>

Local \$aSize[][2] = [ _
[2, 2], _
[5, 2], _
[10, 2], _
[50, 2], _
[100, 2], _
[2, 5], _
[5, 5], _
[10, 5], _
[50, 5], _
[100, 5], _
[2, 10], _
[5, 10], _
[10, 10], _
[50, 10], _
[100, 10] _
]

Local \$aTest, \$aOne, \$aTwo, \$time1, \$time2, \$start

For \$ii = 0 To UBound(\$aSize, 1) - 1
\$aTest = _ArrayGenerator(\$aSize[\$ii][0], \$aSize[\$ii][1])
\$aOne = \$aTest
\$aTwo = \$aTest

\$start = TimerInit()
_ArraySortMethodOne(\$aOne)
\$time1 = TimerDiff(\$start)
ConsoleWrite("_ArraySortMethodOne(" & \$aSize[\$ii][0] & "," & \$aSize[\$ii][1] & ")= " & \$time1 & @LF)

\$start = TimerInit()
_ArraySortMethodTwo(\$aTwo)
\$time2 = TimerDiff(\$start)
ConsoleWrite("_ArraySortMethodTwo(" & \$aSize[\$ii][0] & "," & \$aSize[\$ii][1] & ")= " & \$time2 & @LF)

Next

;~ _ArraySortMethodOne(\$try1)
;~ _ArrayDisplay(\$try1, "_ArraySortMethodOne[ " & TimerDiff(\$start) & "ms ]")

;~ \$start = TimerInit()
;~ _ArraySortMethodTwo(\$try2)
;~ _ArrayDisplay(\$try2, "_ArraySortMethodOne[ " & TimerDiff(\$start) & "ms ]")

Func _ArraySortMethodTwo(ByRef \$arr)
_ArrayTranspose(\$arr)
_ArraySort(\$arr)
_ArrayTranspose(\$arr)
EndFunc   ;==>_ArraySortMethodTwo

Func _ArraySortMethodOne(ByRef \$arr)
Local \$col[UBound(\$arr, 2)][3]
For \$ii = 0 To UBound(\$arr, 2) - 1
\$col[\$ii][0] = \$arr[0][\$ii]
\$col[\$ii][1] = \$ii
Next
Local \$old = \$col
_ArraySort(\$old, 1, 0, 0, 0)
For \$ii = 0 To UBound(\$arr, 2) - 1
\$col[\$ii][1] = \$old[\$ii][2]
Next

For \$ii = 0 To UBound(\$arr, 2) - 1
_ArraySwap(\$arr, \$old[\$ii][1], \$old[\$ii][2], True)
Next
EndFunc   ;==>_ArraySortMethodOne

Func _ArrayGenerator(\$lin = 2, \$col = 2)
Local \$arr[\$lin][\$col]
For \$ii = 0 To UBound(\$arr, 1) - 1
For \$jj = 0 To UBound(\$arr, 2) - 1
Switch \$ii
Case 0
\$arr[\$ii][\$jj] = __RandomName()
Case Else
\$arr[\$ii][\$jj] = StringFormat("%06s", Random(0, 999999, 1))
EndSwitch
Next
Next
Return \$arr
EndFunc   ;==>_ArrayGenerator

Func __RandomName()
Local \$string
For \$ii = 0 To 15
\$string &= Chr(Random(65, 90, 1))
Next
Return \$string
EndFunc   ;==>__RandomName```
Edited by Detefon

Visit my repository

##### Share on other sites

Seens to be ease of coding vs. speed

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2020-09-05 - Version 1.5.1.1) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2020-06-27 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (NEW 2020-06-27 - Version 1.3.2.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
PowerPoint (2017-06-06 - Version 0.0.5.0) - Download - General Help & Support
Excel - Example Scripts - Wiki
Word - Wiki
Task Scheduler (2019-12-03 - Version 1.5.1.0) - Download - General Help & Support - Wiki

Tutorials:
ADO - Wiki, WebDriver - Wiki

##### Share on other sites

this way should be quicker (I think) could you check?

```#include <Array.au3>

Local \$arr[][9] = [ _
['cField', 'aField', 'bField', 'fField', 'eField', 'dField', 'gField', 'iField', 'hField'], _
['333', '111', '222', "666", "555", "444", "777", "999", "888"], _
['333', '111', '222', "666", "555", "444", "777", "999", "888"], _
['333', '111', '222', "666", "555", "444", "777", "999", "888"], _
['333', '111', '222', "666", "555", "444", "777", "999", "888"] _
]

_ArrayTec(\$arr)

Func _ArrayTec(ByRef \$arr)
_ArrayDisplay(\$arr, 'before sort')
__ArrayTecSort(\$arr)
_ArrayDisplay(\$arr, 'after sort')
EndFunc   ;==>_ArrayTec

Func __ArrayTecSort(ByRef \$arr)
Local \$aNDX[UBound(\$arr, 2)][2]
For \$i = 0 To UBound(\$arr, 2) - 1
\$aNDX[\$i][0] = \$arr[0][\$i] ; extract first row
\$aNDX[\$i][1] = \$i ; and set index pre sorting
Next
_ArraySort(\$aNDX) ; sort first row
\$aTemp = \$arr ; clone \$arr to \$aTemp
For \$i = 0 To UBound(\$arr, 1) - 1 ; scan all rows
For \$ii = 0 To UBound(\$arr, 2) - 1 ; scan all columns
\$arr[\$i][\$ii] = \$aTemp[\$i][\$aNDX[\$ii][1]] ; rebuild \$arr using \$aNDX as index
Next
Next
EndFunc   ;==>__ArrayTecSort```

edit

used a little bigger array

Edited by Chimp

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

##### Share on other sites

Great idea to first sort the header row and then re-arrange the data columns

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2020-09-05 - Version 1.5.1.1) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2020-06-27 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (NEW 2020-06-27 - Version 1.3.2.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
PowerPoint (2017-06-06 - Version 0.0.5.0) - Download - General Help & Support
Excel - Example Scripts - Wiki
Word - Wiki
Task Scheduler (2019-12-03 - Version 1.5.1.0) - Download - General Help & Support - Wiki

Tutorials:
ADO - Wiki, WebDriver - Wiki

##### Share on other sites

Great idea to first sort the header row and then re-arrange the data columns

thanks

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

##### Share on other sites

I improved my first _ArrayTec...

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

; \$aSize contain the spec's random array
; create an array with \$aSize[\$lines][\$columns]
Local \$aSize[][2] = [ _
[2, 2], _
[5, 2], _
[10, 2], _
[50, 2], _
[100, 2], _
[2, 5], _
[5, 5], _
[10, 5], _
[50, 5], _
[100, 5], _
[2, 10], _
[5, 10], _
[10, 10], _
[50, 10], _
[100, 10] _
]

Local \$aTest, \$time, \$start

For \$ii = 0 To UBound(\$aSize, 1) - 1
; create an array: _ArrayGenerator(\$lines, \$colums)
\$aTest = _ArrayGenerator(\$aSize[\$ii][0], \$aSize[\$ii][1])

\$start = TimerInit() ; start time of sorting
_ArrayTecSort(\$aTest)
\$time = TimerDiff(\$start) ; end time of sorting
ConsoleWrite("_ArraySortByHeader(" & \$aSize[\$ii][0] & "," & \$aSize[\$ii][1] & ")= " & \$time & "ms to sorting" & @LF)
Next

Func _ArrayTecSort(ByRef \$arr)
Local \$aIndexUnsort = __ArrayHeader(\$arr)
Local \$aIndexSort = __ArrayHeader(\$arr, 1)

Local \$aFrom[1]
Local \$aTo[1]
; verify is \$aFrom and \$aTo is the same postion, if yes, not nothing
; verify if \$aTo[?] is in \$aFrom[?], if yes, not nothing
; verify if \$aFrom[?] is in \$aTo[?], if yes, not nothing
For \$ii = 0 To UBound(\$arr, 2) - 1
If Not (\$aIndexSort[\$ii] == \$aIndexUnsort[\$ii]) And (_ArraySearch(\$aFrom, \$aIndexSort[\$ii]) == -1) And (_ArraySearch(\$aTo, \$aIndexUnsort[\$ii]) == -1) Then
_ArrayAdd(\$aFrom, _ArraySearch(\$arr, \$aIndexUnsort[\$ii], 0, 0, 0, 0, 0, 0, True))
_ArrayAdd(\$aTo, _ArraySearch(\$arr, \$aIndexSort[\$ii], 0, 0, 0, 0, 0, 0, True))
EndIf
Next
For \$ii = 1 To UBound(\$aFrom, 1) - 1
_ArraySwap(\$arr, \$aFrom[\$ii], \$aTo[\$ii], True)
Next

Func __ArrayHeader(\$arr, \$mode = 0)
Local \$ret[1]
For \$ii = 0 To UBound(\$arr, 2) - 1
Next
_ArrayDelete(\$ret, 0)
If \$mode Then _ArraySort(\$ret)
Return \$ret

Func _ArrayGenerator(\$lin = 2, \$col = 2)
Local \$arr[\$lin][\$col]
For \$ii = 0 To UBound(\$arr, 1) - 1
For \$jj = 0 To UBound(\$arr, 2) - 1
Switch \$ii
Case 0
\$arr[\$ii][\$jj] = __RandomName()
Case Else
\$arr[\$ii][\$jj] = StringFormat("%06s", Random(0, 999999, 1))
EndSwitch
Next
Next
Return \$arr
EndFunc   ;==>_ArrayGenerator

Func __RandomName()
Local \$string
For \$ii = 0 To 15
\$string &= Chr(Random(65, 90, 1))
Next
Return \$string
EndFunc   ;==>__RandomName```
Edited by Detefon

Visit my repository

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

• ### Recently Browsing   0 members

×

• Wiki

• Back

• #### Beta

• Git
• FAQ
• Our Picks
×
• Create New...