FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin para Harbour/xHarbour Ordenar matriz multidimensiuonal
Posts: 188
Joined: Wed Feb 01, 2006 06:59 PM
Ordenar matriz multidimensiuonal
Posted: Wed Jun 16, 2010 05:39 PM

Existe la funci贸n ASort que sirve para ordenar una matriz, pero solo de dimensi贸n uno; requiero ordenar una matriz de 10*8, existe alguna funci贸n para esto, o deber茅 gastar un poco de neuronas haciendomela yo mismo. :|

Saludos

Fernando Espinoza

Saludos



Fernando Espinoza
Posts: 244
Joined: Fri Oct 28, 2005 06:29 PM
Re: Ordenar matriz multidimensiuonal
Posted: Wed Jun 16, 2010 06:24 PM
Alejandro Cebolido

Buenos Aires, Argentina
Posts: 652
Joined: Wed Oct 19, 2005 12:03 PM
Re: Ordenar matriz multidimensiuonal
Posted: Wed Jun 16, 2010 06:40 PM

As铆

asort(aVar:aFactura,,,{|x,y| x[1] < y[1]})

luis

Posts: 188
Joined: Wed Feb 01, 2006 06:59 PM
Re: Ordenar matriz multidimensiuonal
Posted: Wed Jun 16, 2010 06:45 PM

Amigo

Revis茅 el enlace y no se si ese ejemplo me pueda servir, ah铆 se esta relacionando dos matrices o yo no lo entiendo bien.

A ver si detallo mas lo m铆o; tengo una sola matriz con una logitud variable de filas, pero columnas son seis (la defino as铆 aMatriz:={{},{},{},{},{},{}); cuando quiero ordenar me refiere a que se pongan de mayor a menor pero tomando como base a los elementos de la columna 1, mas o menos como un indexado pero sobre un solo campo, pero que al ordenar tambi茅n mueva a la nueva posici贸n a los elementos de las columnas 2 a 6 que estan relacionados con el dato de la columna 1. No se si lo explique bien, espero que si; en Excel es facil hacer esto con el comando ordenar.

Saludos

Fernando Espinoza

Saludos



Fernando Espinoza
Posts: 15
Joined: Wed May 03, 2006 02:05 PM
Re: Ordenar matriz multidimensiuonal
Posted: Wed Jun 16, 2010 08:58 PM
Prueba con este codigo

aDatos := {{},{},{},{}}
...
fn_asort(aDatos,1,'A')


Function Fn_ASort(_a,_n1,_AD) //a=Arreglo , n1=Columna a Ordenar , AD='A'Asc.'D'Desc.
Local _aAux,_n,_m,_x,bCondicion
If ValType(_n1)=[B]
bCondicion:=_n1
Else
bCondicion:={||If(_AD='A',_a[_n1,_n]>_a[_n1,_m],_a[_n1,_n]<_a[_n1,_m])}
Endif
For _n=1 To Len(_a[1])
* Status('Ordenando elemento '+Str(Len(_a[1])-_n,10))
For _m=_n+1 To Len(_a[1])
If Eval(bCondicion,_n,_m)
For _x=1 To Len(_a)
_aAux:=_a[_x,_n] ; _a[_x,_n]:=_a[_x,_m] ; _a[_x,_m]:=_aAux
Next
Endif
Next
Next
Return Nil

Francisco N.
Posts: 188
Joined: Wed Feb 01, 2006 06:59 PM
Re: Ordenar matriz multidimensiuonal
Posted: Thu Jun 17, 2010 01:32 AM

Francisco N.

Excelente, funciona perfecto.

Muchas gracias

Saludos



Fernando Espinoza
Posts: 15
Joined: Wed May 03, 2006 02:05 PM
Re: Ordenar matriz multidimensiuonal
Posted: Sat Jun 19, 2010 05:13 AM
Que bueno que te sirvio, la forma como defines los arreglos es como lo vengo trabajando de hace mucho tiempo
aqui te dejo una clase que te puede servir mucho, esto manipula los arreglos como si fuera una tabla/dbf

saludos
Francisco N.

Function TestArray()
Local oDatos
oDatos := tArray():New(5) // ARREGLO DE CINCO COLUMNAS
oDatos:Headers({"codigo","nombre","direccion","direccion_larga"})

oDatos:Append()
oDatos:codigo := "0010"
oDatos:nombre := "JUAN PEREZ"
oDatos:direccion := "AV. TUPAC"
oDatos:direccion_larga := "AV. TUPAC .............."

oDatos:Append()
oDatos:codigo := "0020"
oDatos:nombre := "ANDRES"
oDatos:direccion := "JR. CALLAO"
oDatos:direccion_larga := "JR. CALLAO .............."

oDatos:Append()
oDatos:codigo := "0005"
oDatos:nombre := "PEDRO PEREZ"
oDatos:direccion := "JR. CALLAO"
oDatos:direccion_larga := "JR. CALLAO ..................."

oDatos:SORT("CODIGO") // ordenando por codigo
cReg := ""
oDatos:GoTop()
Do While !oDatos:Eof()
cReg += oDatos:codigo+" "+;
oDatos:nombre+" "+;
oDatos:direccion+" "+;
oDatos:direccion_larga + CHR(13)+CHR(10)

oDatos:Skip()
Enddo
MsgInfo( cReg , "ORDENADO POR CODIGO" )

oDatos:SORT("nombre") // ordenando por nombre
cReg := ""
oDatos:GoTop()
Do While !oDatos:Eof()
cReg += oDatos:codigo+" "+;
oDatos:nombre+" "+;
oDatos:direccion+" "+;
oDatos:direccion_larga + CHR(13)+CHR(10)

oDatos:Skip()
Enddo
MsgInfo( cReg , "ORDENADO POR NOMBRE" )
Return Nil
//----------------------------------------------------------------------------//
#include "FiveWin.ch"
//----------------------------------------------------------------------------//
CLASS TArray

DATA aData AS ARRAY
DATA nAt
DATA lHeaders,aFldNames
DATA lEof,lBof

METHOD New() CONSTRUCTOR

METHOD Sort( nCol )
METHOD GoTop() INLINE ::nAt := 1,::Skip(0)
METHOD GoBottom() INLINE ::nAt := ::LastRec(),::Skip(0)
METHOD Skip(nWant,nOld) INLINE nWant := If(nWant=Nil,1,nWant),;
nOld := ::nAt, ::nAt += nWant,;
::= ::nAt>::LastRec(),;
::= ::nAt<::LastRec(),;
::nAt := Max( 1, Min(::nAt,::LastRec()) ),;
::nAt - nOld
METHOD Eof() INLINE ::lEof
METHOD Recno() INLINE ::nAt
METHOD LastRec() INLINE Len(::aData[1])
METHOD GoTo( nRecno ) INLINE ::nAt:=nRecno,::Skip(0)
METHOD Append()
METHOD fCount() INLINE Len(::aData)

METHOD Headers(aHeaders)
METHOD FieldName( nField ) INLINE ::aFldNames[ nField ]

METHOD FieldPos( cFieldName )
MESSAGE FieldPut METHOD _FieldPut( nField, uVal )
MESSAGE FieldGet METHOD _FieldGet( nField )

ERROR HANDLER OnError( uParam1 )

ENDCLASS
//---------------------------------------------------------------------------//
METHOD New(nCol) CLASS tArray
Local m
::nAt:= 0
::aFldNames:={}
::lHeaders := .f.
If ValType(nCol)="A"
::aData := nCol
Else
::aData :={}
For m=1 To nCol
Aadd( ::aData,{})
Next
EndIf
Return Self
*----------------------------------------------------------------------------*
METHOD Sort(nCol,_AD) CLASS tArray //a=Arreglo , n1=Columna , AD='A'Asc.'D'Desc.
Local aDataAux,_n,_m,_x,bCondicion
If ValType(nCol)="C"
nCol := ::FieldPos(nCol)
EndIf
nCol:=If(nCol=Nil,1,nCol)
_AD :=If(_AD =Nil,"A",_AD)
If ValType(_AD)=[B]
bCondicion:=_AD
Else
bCondicion:={||If(_AD='A',::aData[nCol,_n]>::aData[nCol,_m],::aData[nCol,_n]<::aData[nCol,_m])}
Endif
For _n=1 To Len(::aData[1])
For _m=_n+1 To Len(::aData[1])
If Eval(bCondicion,_n,_m)
For _x=1 To Len(::aData)
aDataAux:=::aData[_x,_n] ; ::aData[_x,_n]:=::aData[_x,_m] ; ::aData[_x,_m]:=aDataAux
Next
Endif
Next
Next
::GoTop()
Return 0
*----------------------------------------------------------------------------*
METHOD OnError( uParam1 ) CLASS TArray
Local cMsg := __GetMessage()
Local nError := If( SubStr( cMsg, 1, 1 ) == "_", 1005, 1004 )
Local nField
If SubStr( cMsg, 1, 1 ) == "_"
if( ( nField := ::FieldPos( SubStr( cMsg, 2 ) ) ) != 0 )
::FieldPut( nField, uParam1 )
else
_ClsSetError( _GenError( nError, ::ClassName(), SubStr( cMsg, 2 ) ) )
endif
Else
if( ( nField := ::FieldPos( cMsg ) ) != 0 )
return ::FieldGet( nField )
else
_ClsSetError( _GenError( nError, ::ClassName(), cMsg ) )
endif
Endif
Return nil
//----------------------------------------------------------------------------//
METHOD _FieldPut( nPos, uValue ) CLASS tArray
::aData[nPos,::nAt] := uValue
Return nil
//----------------------------------------------------------------------------//
METHOD _FieldGet( nPos ) CLASS TArray
If nPos=0
MsgInfo( "Objeto Variable, "+::aFldNames[ nPos ]+", No Inicializada"+Chr(13)+;
" Called from " + Trim( ProcName( 3 ) ) + ;
"(" + Str( ProcLine( 3 ),5 ) + ")" )
Endif
Return ::aData[nPos,::nAt]
//----------------------------------------------------------------------------//
METHOD FieldPos( cFieldName,uValor ) CLASS TArray
Local nInd:=Ascan(::aFldNames,cFieldName )
If (nInd:=Ascan(::aFldNames,( cFieldName:=Upper(AllTrim(cFieldName)) )))=0
Alert("No Existe, "+cFieldName)
Return 0
Else
Return nInd
Endif
Return Nil
//----------------------------------------------------------------------------//
METHOD Append() CLASS TArray
Local nCol:=0
aEval(Array(::fCount()),{|| nCol++,Aadd(::aData[nCol],0) })
::GoBottom()
Return Nil
//----------------------------------------------------------------------------//
METHOD Headers(aHeaders) CLASS TArray
::aFldNames := {}
aEval(aHeaders,{|x| AAdd( ::aFldNames,Upper(x) ) })
::lHeaders := .t.
Return Nil
//----------------------------------------------------------------------------//
Posts: 33
Joined: Sun May 14, 2006 07:31 AM
ordenar array basico
Posted: Thu Jul 15, 2010 07:44 PM
Function Fn_ASort(matriz,columna,orden) // orden='A'Asc.'D'Desc.
Local _aAux,_n,_m,_x,bCondicion
If ValType(columna)=[B]
bCondicion:=columna
Else
bCondicion:={||If(orden='A',matriz[columna,_n]>matriz[columna,_m],matriz[columna,_n]<matriz[columna,_m])}
Endif
For _n=1 To Len(matriz)
For _m=_n+1 To Len(matriz)
If matriz[_n]>matriz[_m]
For _x=1 To Len(matriz)
_aAux:=matriz[_n]
matriz[_n]:=matriz[_m]
matriz[_m]:=_aAux
Next
Endif
Next
Next
Return Nil

Continue the discussion