Max(Max(Max()))

Aqui você poderá oferecer suas Contribuições, Dicas e Tutoriais (Texto ou Vídeo) que sejam de interesse de todos.

Moderador: Moderadores

Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Max(Max(Max()))

Mensagem por JoséQuintas »

Pensei aqui....
No MySQL, colocamos uma lista para escolher o maior valor.
No Harbour poderia ter igual.
Até pensei que tinha, mas não tem.

A saída é criar uma, com o detalhe de que lista no Harbour é array.

Código: Selecionar todos

FUNCTION AMax( aList )

   LOCAL xMax

   IF ValType( aList ) == "A" .AND. Len( aList ) > 0
      xMax := aList[ 1 ]
      AEval( aList, { | e | xMax := Max( xMax, e } )
   ENDIF

   RETURN xMax
Agora só usar
? AMax( { 1, 2, 3, 4, 5 } )
? AMax( { "A", "B", "C", "D" } )

Agora não tem conflito com a Max existente.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Max(Max(Max()))

Mensagem por JoséQuintas »

Achei chato o uso.
Agora optei por criar com o mesmo nome do MySQL.

Código: Selecionar todos

FUNCTION Greatest( ... )

   LOCAL aList, xValue

   aList := hb_AParams()

   IF ValType( aList ) == "A" .AND. Len( aList ) > 0
      xValue := aList[ 1 ]
      AEval( aList, { | e | xValue := Max( xValue, e ) } )
   ENDIF

   RETURN xValue
Pra poder usar Greatest( 10, 9, 8, 7 )
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Max(Max(Max()))

Mensagem por alxsts »

Olá!

No passado também precisei deste tipo de função e também criei. Interessante que uma delas eu batizei com o nome AMax(), para manter a semelhança com os nomes de funções de array do Cl*pper. A diferença é que as minhas tratam arrays multidimensionais.

Código: Selecionar todos

// Testes de funções diversas (aggregate)
// Compilar: hbmk2 teste -w3 -es2 -run
// Alexandre Santos

FUNCTION Teste()

   LOCAL aUni := { 50,81,23,96,81 }, aUf

   REQUEST HB_LANG_PT          
   REQUEST HB_CODEPAGE_PTISO
   HB_CDPSELECT("PTISO")

   aUf := { ;//Região          UF    Nome UF               Área     Popula. Municípios 
            { "Norte",        "AC", "Acre",                164123,   869265,  22 }, ;
            { "Norte",        "AM", "Amazonas",           1559146,  4080611,  62 }, ;
            { "Norte",        "AP", "Amapá",               142828,   829494,  16 }, ;
            { "Norte",        "TO", "Tocantins",           277620,  1550194, 139 }, ;
            { "Norte",        "PA", "Pará",               1247954,  8578051, 144 }, ;
            { "Norte",        "RR", "Roraima",             224300,   576568,  15 }, ;
            { "Norte",        "RO", "Rondônia",            237590,  1787279,  52 }, ;
            { "Nordeste",     "CE", "Ceará",               148920,  9075649, 184 }, ;
            { "Nordeste",     "AL", "Alagoas",              27848,  3322820, 102 }, ;
            { "Nordeste",     "BA", "Bahia",               584733, 14812617, 417 }, ;
            { "Nordeste",     "MA", "Maranhão",            331937,  7035055, 217 }, ;
            { "Nordeste",     "PB", "Paraíba",              56469,  3996496, 223 }, ;
            { "Nordeste",     "PE", "Pernambuco",           98149,  9496294, 185 }, ;
            { "Nordeste",     "PI", "Piauí",               251577,  3264531, 224 }, ;
            { "Nordeste",     "RN", "Rio Grande do Norte",  52811,  3479010, 167 }, ;
            { "Nordeste",     "SE", "Sergipe",              21915,  2278308,  75 }, ;
            { "Centro-Oeste", "GO", "Goiás",               340111,  6991161, 246 }, ;
            { "Centro-Oeste", "MT", "Mato Grosso",         903378,  3441998, 141 }, ;
            { "Centro-Oeste", "MS", "Mato Grosso do Sul",  357145,  2478023,  77 }, ;
            { "Centro-Oeste", "DF", "Distrito Federal",      5779,  3039444,   1 }, ;
            { "Sudeste",      "ES", "Espírito Santo",       46095,  4016356,  78 }, ;
            { "Sudeste",      "MG", "Minas Gerais",        586522, 21119536, 853 }, ;
            { "Sudeste",      "RJ", "Rio de Janeiro",       43780, 16718956,  92 }, ;
            { "Sudeste",      "SP", "São Paulo",           248222, 45538936, 645 }, ;
            { "Sul",          "PR", "Paraná",              199307, 11348937, 399 }, ;
            { "Sul",          "SC", "Santa Catarina",       95736,  6910553, 295 }, ;
            { "Sul",          "RS", "Rio Grande do Sul",   281730, 11329605, 497 } ;
          }

   SetMode( 43,120 )
   CLS

   SetPos( 10,10) ; QOut( "Maior população por estado ", AMax( aUF, 5 ) )
   SetPos( 11,10) ; QOut( "Menor população por estado ", AMin( aUF, 5 ) )
   SetPos( 12,10) ; QOut( "População Média ", AAvg( aUF, 5 ) )
   SetPos( 13,10) ; QOut( "Qtd. Municípios Região Sul ", ASum( aUF, 6, { |x| x[1] == "Sul" } ) )
   SetPos( 14,10) ; QOut( "Qtd. Estados Região Norte ", ACount( aUF, { |x| x[1] == "Norte" } ) )
   SetPos( 15,10) ; QOut( "Qtd. Estados Região Sul+Norte ", ACount( aUF, { |x| x[1] $ "Sul;Norte" } ) )
   SetPos( 17,10) ; QOut( Replicate( "-", 70 ) )
   SetPos( 19,10) ; QOut( "Max Unidimensional ", AMax( aUni ) )
   SetPos( 20,10) ; QOut( "Min Unidimensional ", AMin( aUni ) )
   SetPos( 21,10) ; QOut( "Sum Unidimensional ", ASum( aUni ) )
   SetPos( 22,10) ; QOut( "Avg Unidimensional ", AAvg( aUni ) )
   SetPos( 23,10) ; QOut( "ACount Unidimensional ", ACount( aUni, { |x| x == 81 } ) )

   Inkey(0)

RETURN NIL
//----------------------------------------------------------------------------------------------------

FUNCTION AMax( aArray, nCol )
   // Alexandre Santos
   LOCAL xVal

   If ( ValType( aArray ) == "A" .And. ! Empty( aArray ) )
      If ( ValType( aArray[1] ) == "A" .And. ! Empty( aArray[1] ) )
         // Multidimensional
         If ( Valtype( nCol ) != "N" .Or. ( Valtype( nCol ) == "N" .And. nCol > Len( aArray[1] ) ) )
            nCol := 1
         Endif
         xVal := aArray[1,nCol]
         AEval( aArray, { |e| xVal := If( e[nCol] != NIL .And. e[nCol] > xVal, e[nCol], xVal ) } )
      Else
         // Unidimensional
         xVal := aArray[1]
         AEval( aArray, { |e| xVal := If( e != NIL .And. e > xVal, e, xVal ) } )
      Endif
   Endif

RETURN xVal
//----------------------------------------------------------------------------------------------------
FUNCTION AMin( aArray, nCol )
   // Alexandre Santos
   LOCAL xVal

   If ( ValType( aArray ) == "A" .And. ! Empty( aArray ) )
      If ( ValType( aArray[1] ) == "A" .And. ! Empty( aArray[1] ) )
         // Multidimensional
         If ( Valtype( nCol ) != "N" .Or. ( Valtype( nCol ) == "N" .And. nCol > Len( aArray[1] ) ) )
            nCol := 1
         Endif
         xVal := aArray[1,nCol]
         AEval( aArray, { |e| xVal := If( e[nCol] != NIL .And. e[nCol] < xVal, e[nCol], xVal ) } )
      Else
         // Unidimensional
         xVal := aArray[1]
         AEval( aArray, { |e| xVal := If( e != NIL .And. e < xVal, e, xVal ) } )
      Endif
   Endif

RETURN xVal
//----------------------------------------------------------------------------------------------------
FUNCTION ASum( aArray, nCol, bFor )
   // Alexandre Santos
   LOCAL nVal := 0

   If ( ValType( aArray ) == "A" .And. ! Empty( aArray ) )
      If ( ValType( aArray[1] ) == "A" .And. ! Empty( aArray[1] ) )
         // Multidimensional
         If ( Valtype( nCol ) != "N" .Or. ( Valtype( nCol ) == "N" .And. nCol > Len( aArray[1] ) ) )
            nCol := 1
         Endif
         bFor := If( Valtype( bFor ) != "B", { || .T. }, bFor )  
         AEval( aArray, { |e| nVal += If( Valtype( e[nCol] ) == "N" .And. Eval( bFor, e, nCol ), e[nCol], 0 ) } )
      Else
         // Unidimensional
         AEval( aArray, { |e| nVal += If( Valtype( e ) == "N", e, 0 ) } )
      Endif
   Endif

RETURN nVal
//----------------------------------------------------------------------------------------------------

FUNCTION AAvg( aArray, nCol )
   // Alexandre Santos
   LOCAL nVal := 0

   If ( ValType( aArray ) == "A" .And. ! Empty( aArray ) )
      If ( ValType( aArray[1] ) == "A" .And. ! Empty( aArray[1] ) )
         // Multidimensional
         If ( Valtype( nCol ) != "N" .Or. ( Valtype( nCol ) == "N" .And. nCol > Len( aArray[1] ) ) )
            nCol := 1
         Endif
         nVal := ASum( aArray, nCol )
      Else
         // Unidimensional
         nVal := ASum( aArray )
      Endif
   Endif

RETURN ( nVal / Len( aArray ) )
//----------------------------------------------------------------------------------------------------
FUNCTION ACount( aArray, bFilter )
   // Alexandre Santos
   LOCAL nCount := 0

   bFilter := If( Valtype( bFilter ) != "B", { || .T. }, bFilter )

   If ( Valtype( aArray ) == "A" .And. ! Empty( aArray ) )
      AEval( aArray, { |e| nCount += If( Eval( bFilter, e ), 1, 0 ) } )
   Endif

RETURN nCount
//----------------------------------------------------------------------------------------------------
Resultados dos testes.

Código: Selecionar todos

Maior população por estado    45538936
Menor população por estado      576568
População Média     7702435.07
Qtd. Municípios Região Sul        1191
Qtd. Estados Região Norte           7
Qtd. Estados Região Sul+Norte          10

----------------------------------------------------------------------

Max Unidimensional          96
Min Unidimensional          23
Sum Unidimensional         331
Avg Unidimensional          66.20
ACount Unidimensional           2
[]´s
Alexandre Santos (AlxSts)
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Max(Max(Max()))

Mensagem por JoséQuintas »

De repente, a intenção poderia ser mostrar a UF com maior população.
Nesse caso, não sei se o mais correto seria AMax() retornar o maior número, ou o elemento do array com maior número.
Acabaria sendo o "maior array" da lista.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
mauricioportela
Usuário Nível 2
Usuário Nível 2
Mensagens: 95
Registrado em: 29 Jul 2016 04:22
Localização: Vitoria da Conquista/Bahia

Max(Max(Max()))

Mensagem por mauricioportela »

Olá Quintas!

Uma alternativa:

Código: Selecionar todos

FUNCTION Main()
    //        Região          UF    Nome UF               Área     Popula. Municípios
    aUf := { { "Norte",        "AC", "Acre",                164123,   869265,  22 }, ;
             { "Norte",        "AM", "Amazonas",           1559146,  4080611,  62 }, ;
             { "Norte",        "AP", "Amapá",               142828,   829494,  16 }, ;
             { "Norte",        "TO", "Tocantins",           277620,  1550194, 139 }, ;
             { "Norte",        "PA", "Pará",               1247954,  8578051, 144 }, ;
             { "Norte",        "RR", "Roraima",             224300,   576568,  15 }, ;
             { "Norte",        "RO", "Rondônia",            237590,  1787279,  52 }, ;
             { "Nordeste",     "CE", "Ceará",               148920,  9075649, 184 }, ;
             { "Nordeste",     "AL", "Alagoas",              27848,  3322820, 102 }, ;
             { "Nordeste",     "BA", "Bahia",               584733, 14812617, 417 }, ;
             { "Nordeste",     "MA", "Maranhão",            331937,  7035055, 217 }, ;
             { "Nordeste",     "PB", "Paraíba",              56469,  3996496, 223 }, ;
             { "Nordeste",     "PE", "Pernambuco",           98149,  9496294, 185 }, ;
             { "Nordeste",     "PI", "Piauí",               251577,  3264531, 224 }, ;
             { "Nordeste",     "RN", "Rio Grande do Norte",  52811,  3479010, 167 }, ;
             { "Nordeste",     "SE", "Sergipe",              21915,  2278308,  75 }, ;
             { "Centro-Oeste", "GO", "Goiás",               340111,  6991161, 246 }, ;
             { "Centro-Oeste", "MT", "Mato Grosso",         903378,  3441998, 141 }, ;
             { "Centro-Oeste", "MS", "Mato Grosso do Sul",  357145,  2478023,  77 }, ;
             { "Centro-Oeste", "DF", "Distrito Federal",      5779,  3039444,   1 }, ;
             { "Sudeste",      "ES", "Espírito Santo",       46095,  4016356,  78 }, ;
             { "Sudeste",      "MG", "Minas Gerais",        586522, 21119536, 853 }, ;
             { "Sudeste",      "RJ", "Rio de Janeiro",       43780, 16718956,  92 }, ;
             { "Sudeste",      "SP", "São Paulo",           248222, 45538936, 645 }, ;
             { "Sul",          "PR", "Paraná",              199307, 11348937, 399 }, ;
             { "Sul",          "SC", "Santa Catarina",       95736,  6910553, 295 }, ;
             { "Sul",          "RS", "Rio Grande do Sul",   281730, 11329605, 497 } }

    nMaiorValor := 0
    nMenorValor := aUf[1][5]
    nMedia := 0

    aLista1 := { 5, 9, 2, 1, 4, 6, 7, 8 }
    aLista2 := { "Z", "B", "A", "F", "C", "D" }

    FOR x := 1 TO LEN(aUf)
        IIF( (nMaiorValor < aUf[x][5]), nMaiorValor := aUf[x][5], nMaiorValor := nMaiorValor)
    NEXT

    FOR x := 1 TO LEN(aUf)
        IIF( (nMenorValor > aUf[x][5]), nMenorValor := aUf[x][5], nMenorValor := nMenorValor)
    NEXT

    FOR x := 1 TO LEN(aUf)
        nMedia += aUf[x][5]
    NEXT

    ? "MAIOR em populacao : ", nMaiorValor
    ? "MENOR em populacao : ", nMenorValor
    ? "MEDIA em populacao : ", (nMedia /= LEN(aUf))

    ? hb_ValToExp(ASort( aLista1,,,{| x, y | x < y } ))
    ? hb_ValToExp(ASort( aLista1,,,{| x, y | x > y } ))
    
    ? hb_ValToExp(ASort( aLista2,,,{| x, y | x < y } ))
    ? hb_ValToExp(ASort( aLista2,,,{| x, y | x > y } ))
RETURN Nil


Att
Mauricio
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Max(Max(Max()))

Mensagem por alxsts »

Olá!
JoséQuintas escreveu:Nesse caso, não sei se o mais correto seria AMax() retornar o maior número, ou o elemento do array com maior número
Acho que retornar a posição no vetor fica melhor pois libera o acesso a todas as colunas da linha onde se encontra a coluna com o maior/menor valor:

Código: Selecionar todos

//----------------------------------------------------------------------------------------------------

FUNCTION AMax( aArray, nCol )
   // Alexandre Santos
   LOCAL xVal, nPos := 0, bBlock := { |v,p| xVal := v, nPos := p }

   If ( ValType( aArray ) == "A" .And. ! Empty( aArray ) )
      If ( ValType( aArray[1] ) == "A" .And. ! Empty( aArray[1] ) )
         // Multidimensional
         If ( Valtype( nCol ) != "N" .Or. ( Valtype( nCol ) == "N" .And. nCol > Len( aArray[1] ) ) )
            nCol := 1
         Endif
         xVal := aArray[1,nCol]
         AEval( aArray, { |e,p| If( e[nCol] != NIL .And. e[nCol] > xVal, Eval( bBlock, e[nCol], p), NIL ) } )
      Else
         // Unidimensional
         xVal := aArray[1]
         AEval( aArray, { |e,p| If( e != NIL .And. e > xVal, Eval( bBlock, e, p), NIL ) } )
      Endif
   Endif

RETURN nPos
//----------------------------------------------------------------------------------------------------
FUNCTION AMin( aArray, nCol )
   // Alexandre Santos
   LOCAL xVal, nPos := 0, bBlock := { |v,p| xVal := v, nPos := p }

   If ( ValType( aArray ) == "A" .And. ! Empty( aArray ) )
      If ( ValType( aArray[1] ) == "A" .And. ! Empty( aArray[1] ) )
         // Multidimensional
         If ( Valtype( nCol ) != "N" .Or. ( Valtype( nCol ) == "N" .And. nCol > Len( aArray[1] ) ) )
            nCol := 1
         Endif
         xVal := aArray[1,nCol]
         AEval( aArray, { |e,p| If( e[nCol] != NIL .And. e[nCol] < xVal, Eval( bBlock, e[nCol], p), NIL ) } )
      Else
         // Unidimensional
         xVal := aArray[1]
         AEval( aArray, { |e,p| If( e != NIL .And. e < xVal, Eval( bBlock, e, p), NIL ) } )
      Endif
   Endif

RETURN nPos
//----------------------------------------------------------------------------------------------------

Código: Selecionar todos

SetPos( 10,10) ; QOut( "Maior população por estado ", aUF[ ( nPos := AMax( aUF, 5 ) ), 3 ], aUF[ nPos, 5 ] ) 
SetPos( 11,10) ; QOut( "Menor população por estado ", aUF[ ( nPos := AMin( aUF, 5 ) ), 3 ], aUF[ nPos, 5 ] )

Maior população por estado  São Paulo   45538936
Menor população por estado  Roraima     576568 
[]´s
Alexandre Santos (AlxSts)
Responder