Sort multidimensional array by one of their values

Y have a multidimensional array:

x(0,0) = 1
x(0,1) = 5
x(0,2) = 8

x(1,0) = 3
x(1,1) = 6
x(1,2) = 1

x(2,0) = 2
x(2,1) = 3
x(2,2) = 9

How can I sort the entire matrix taking only the third value (ubound 2) of each?

Copy those values into a new array and use sortWith?

Yes, I did that, but I thought there could be some function to sort directly without separating the array.
Thanks.

multi dimensional array are not sortable using the array methods built in to Xojo
it would be possible to write a custom sort routine that did though

Could you refactor the multidimensional array as class instances? If so, you can do something like what is described in this blog entry.

This has come up before and except for simple sorting cases I think the in-memory database approach seems to be the better way. You can find a recent discussion on this on the following post: https://forum.xojo.com/55796-sorting-data-array-or-dictionary-with-5-columns

or just pull the specific column values into a one d array
and the row indexes into another

use sortwith on the values then access the specific rows through the indexes array

there are lots of ways to do something like this

new desktop project
in window1.open event I have

Const limit = 199999
Dim r As New random
Dim orig(limit,2) As Integer

For i As Integer = 0 To limit
  orig(i,0) = r.inrange(0,limit)
  orig(i,1) = r.inrange(0,limit)
  orig(i,2) = r.inrange(0,limit)
Next

Dim x(limit,2) As Integer
For i As Integer = 0 To limit
  For j As Integer = 0 To 2
    x(i,j) = orig(i,j)
  Next
Next
// x(0,0) = 1
// x(0,1) = 5
// x(0,2) = 8
// 
// x(1,0) = 3
// x(1,1) = 6
// x(1,2) = 1
// 
// x(2,0) = 2
// x(2,1) = 3
// x(2,2) = 9

Dim startTime As Double = Microseconds
x.sortBy1(2)
Dim endTime As Double = Microseconds

Dim elapsed1 As Double = endTime - startTime

For i As Integer = 0 To limit
  For j As Integer = 0 To 2
    x(i,j) = orig(i,j)
  Next
Next

startTime = Microseconds
x.sortBy2(2)
endTime = Microseconds

Dim elapsed2 As Double = endTime - startTime

Break

as well I added a module
in there I put

Public Sub SortBy1(extends arr(, ) as integer, column as integer)
  Dim rows As Integer = ubound(arr,1)
  Dim cols As Integer = ubound(arr,2)
  
  Dim values() As Integer
  Dim indexes() As Integer
  
  For i As Integer = 0 To rows
    values.append arr(i, column)
    indexes.Append i
  Next
  
  values.SortWith indexes
  
  Dim newarr(-1,-1) As Integer
  Redim newarr(rows,cols)
  For row As Integer = 0 To rows
    Dim readRow As Integer = indexes(row)
    For col As Integer = 0 To cols
      newarr(row,col) = arr(readrow,col)
    Next
  Next
  
  Redim arr(-1,-1)
  Redim arr(rows,cols)
  For row As Integer = 0 To rows
    For col As Integer = 0 To cols
      arr(row,col) = newarr(row,col)
    Next
  Next
  
  
End Sub

and

Public Sub SortBy2(extends arr(, ) as integer, column as integer)
  Dim rows As Integer = ubound(arr,1)
  Dim cols As Integer = ubound(arr,2)
  
  
  Dim sqlDB As New SQLiteDatabase
  Call sqlDB.Connect
  Dim colNames() As String
  For i As Integer = 0 To cols
    colNames.append "col" + Str(i)
  Next
  Dim sql As String = "create table temp(" + Join(colNames,",") + ")"
  sqlDB.SQLExecute(sql)
  
  sqldb.SQLExecute("begin transaction")
  For row As Integer = 0 To rows
    
    Dim colValues() As String 
    For col As Integer = 0 To cols
      colValues.append Str(arr(row,col))
    Next
    sql = "insert into temp(" + Join(colNames,",") + ") values (" + Join(colValues,",") + ")"
    sqlDB.SQLExecute(sql)
    
  Next
  sqldb.SQLExecute("commit transaction")
  
  Redim arr(-1,-1)
  Redim arr(rows,cols)
  Dim rs As recordset 
  sql= "select * from temp order by " + colNames(column)
  rs = sqlDB.SQLSelect(sql)
  Dim row As Integer = 0
  While rs <> Nil And rs.eof <> True
    
    For col As Integer = 0 To cols
      arr(row,col) = rs.idxFIeld(col+1).IntegerValue
    Next
    
    row = row + 1
    rs.movenext
  Wend
End Sub

the in place in memory version is much faster than the sqlite DB with this data set
BUT it will also use twice as much memory as the original array size