Sign in to follow this  
Followers 0
gerwim

Select lowest from array but not 0

6 posts in this topic

Hey guys,

So I've got this array:

$aPing[0] = "90"
$aPing[1] = "50"
$aPing[2] = "0"
$aPing[3] = "10"

(Beware, this is just a non working example, but you get the point).

Now I want to select the fourth ($aPing[3]) because it's the lowest (it needs to be higher than 0). I'm using _ArrayMin now, but that will select the third ($aPing[2]) nonetheless.

Is there any other function I can use to give extra parameters (or atleast make it select the fourth array? This array is dynamic though, so values are changeable).

Thanks in advance,

Gerwim

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

Here my 1st idea:

#include <Array.au3>
Dim $aPing[4]
$aPing[0] = 90
$aPing[1] = 50
$aPing[2] = 0
$aPing[3] = 10

_ArraySort($aPing)
For $i = 0 To UBound($aPing) - 1
    If $aPing[$i] > 0 Then
        MsgBox(0, "Information", "Smallest number (exept zero): " & $aPing[$i], 10)
        ExitLoop
    EndIf
Next

Br,

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

_ArraySort() does not sort numerical. I use the excellent _ArraySortClib() from Siao for this (disadvantage: only 32bit).

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseUpx=n
#AutoIt3Wrapper_UseX64=n
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <array.au3>

Dim $aPing[5]
$aPing[0] = "90"
$aPing[1] = "50"
$aPing[2] = "0"
$aPing[3] = "10"
$aPing[4] = "6"

_ArraySort($aPing)
For $i = 0 To UBound($aPing) - 1
    If $aPing[$i] > 0 Then
        MsgBox(0, "Information", "Smallest number (exept zero): " & $aPing[$i], 10)
        ExitLoop
    EndIf
Next




$h_DLL_user32 = DllOpen("user32.dll")
$h_DLL_msvcrt = DllOpen("msvcrt.dll")
$h_DLL_Kernel32 = DllOpen("kernel32.dll")
OnAutoItExitRegister("_OnExitCloseDlls")

_ArraySortClib($aPing, 0)
For $i = 0 To UBound($aPing) - 1
    If $aPing[$i] > 0 Then
        MsgBox(0, "Information", "Smallest number (exept zero): " & $aPing[$i], 10)
        ExitLoop
    EndIf
Next

Func _OnExitCloseDlls()
    DllClose($h_DLL_user32)
    DllClose($h_DLL_msvcrt)
    DllClose($h_DLL_Kernel32)
EndFunc   ;==>_OnExitCloseDlls


; http://www.autoitscript.com/forum/index....p?showtopic=63525&view=findpos
;===============================================================================
; Function Name:    _ArraySortClib() v4
; Description:         Sort 1D/2D array using qsort() from C runtime library
; Syntax:
; Parameter(s):      $Array - the array to be sorted, ByRef
;                    $iMode - sort mode, can be one of the following:
;                        0 = numerical, using double precision float compare
;                        1 = string sort, case insensitive (default)
;                        2 = string sort, case sensitive
;                        3 = word sort, case insensitive - compatible with AutoIt's native compare
;                    $fDescend - sort direction. True = descending, False = ascending (default)
;                    $iStart - index of starting element (default 0 = $array[0])
;                    $iEnd - index of ending element (default 0 = Ubound($array)-1)
;                    $iColumn - index of column to sort by (default 0 = first column)
;                    $iStrMax - max string length of each array element to compare (default 4095 chars)
; Requirement(s):    msvcrt.dll (shipped with Windows since Win98 at least), 32-bit version of AutoIt
; Return Value(s):    Success = Returns 1
;                    Failure = Returns 0 and sets error:
;                        @error 1 = invalid array
;                        @error 2 = invalid param
;                        @error 3 = dll error
;                        @error 64 = 64-bit AutoIt unsupported
; Author(s):   Siao
; Modification(s):
;===============================================================================

Func _ArraySortClib(ByRef $array, $iMode = 1, $fDescend = False, $iStart = 0, $iEnd = 0, $iColumn = 0, $iStrMax = 4095)
    If @AutoItX64 Then Return SetError(64, 0, 0)
    Local $iArrayDims = UBound($array, 0)
    If @error Or $iArrayDims > 2 Then Return SetError(1, 0, 0)
    Local $iArraySize = UBound($array, 1), $iColumnMax = UBound($array, 2)
    If $iArraySize < 2 Then Return SetError(1, 0, 0)
    If $iEnd < 1 Or $iEnd > $iArraySize - 1 Then $iEnd = $iArraySize - 1
    If ($iEnd - $iStart < 2) Then Return SetError(2, 0, 0)
    If $iArrayDims = 2 And ($iColumnMax - $iColumn < 0) Then Return SetError(2, 0, 0)
    If $iStrMax < 1 Then Return SetError(2, 0, 0)
    Local $i, $j, $iCount = $iEnd - $iStart + 1, $fNumeric, $aRet, $sZero = ChrW(0), $sStrCmp, $sBufType = 'byte[', $tSource, $tIndex, $tFloatCmp, $tCmpWrap = DllStructCreate('byte[64]'), $tEnumProc = DllStructCreate('byte[64]')

    If $h_DLL_msvcrt = -1 Then Return SetError(3, 0, 0)
    ;; initialize compare proc
    Switch $iMode
        Case 0
            $fNumeric = True
            $tFloatCmp = DllStructCreate('byte[36]')
            DllStructSetData($tFloatCmp, 1, '0x8B4C24048B542408DD01DC1ADFE0F6C440750D80E441740433C048C333C040C333C0C3')
            DllStructSetData($tCmpWrap, 1, '0xBA' & Hex(Binary(DllStructGetPtr($tFloatCmp)), 8) & '8B4424088B4C2404FF30FF31FFD283C408C3')
            DllStructSetData($tEnumProc, 1, '0x8B7424048B7C24088B4C240C8B442410893789470483C60883C708404975F1C21000')
        Case 1, 2
            $sStrCmp = "_strcmpi" ;case insensitive
            If $iMode = 2 Then $sStrCmp = "strcmp" ;case sensitive
            $aRet = DllCall($h_DLL_Kernel32, 'ptr', 'GetModuleHandle', 'str', 'msvcrt.dll')
            $aRet = DllCall($h_DLL_Kernel32, 'ptr', 'GetProcAddress', 'ptr', $aRet[0], 'str', $sStrCmp)
            ;If $aRet[0] = 0 Then Return SetError(3, 0, 0 * DllClose($h_DLL_msvcrt))
            If $aRet[0] = 0 Then Return SetError(3, 0, 1)
            DllStructSetData($tCmpWrap, 1, '0xBA' & Hex(Binary($aRet[0]), 8) & '8B4424088B4C2404FF30FF31FFD283C408C3')
            DllStructSetData($tEnumProc, 1, '0x8B7424048B7C24088B4C240C8B542410893789570483C7088A064684C075F9424975EDC21000')
        Case 3
            $sBufType = 'wchar['
            $aRet = DllCall($h_DLL_Kernel32, 'ptr', 'GetModuleHandle', 'str', 'kernel32.dll')
            $aRet = DllCall($h_DLL_Kernel32, 'ptr', 'GetProcAddress', 'ptr', $aRet[0], 'str', 'CompareStringW')
            ;If $aRet[0] = 0 Then Return SetError(3, 0, 0 * DllClose($h_DLL_msvcrt))
            If $aRet[0] = 0 Then Return SetError(3, 0, 1)
            DllStructSetData($tCmpWrap, 1, '0xBA' & Hex(Binary($aRet[0]), 8) & '8B4424088B4C24046AFFFF306AFFFF3168000000006800040000FFD283E802C3')
            DllStructSetData($tEnumProc, 1, '0x8B7424048B7C24088B4C240C8B542410893789570483C7080FB70683C60285C075F6424975EAC21000')
        Case Else
            Return SetError(2, 0, 0)
    EndSwitch
    ;; write data to memory
    If $fNumeric Then
        $tSource = DllStructCreate('double[' & $iCount & ']')
        If $iArrayDims = 1 Then
            For $i = 1 To $iCount
                DllStructSetData($tSource, 1, $array[$iStart + $i - 1], $i)
            Next
        Else
            For $i = 1 To $iCount
                DllStructSetData($tSource, 1, $array[$iStart + $i - 1][$iColumn], $i)
            Next
        EndIf
    Else
        Local $sMem = ""
        If $iArrayDims = 1 Then
            For $i = $iStart To $iEnd
                $sMem &= StringLeft($array[$i], $iStrMax) & $sZero
            Next
        Else
            For $i = $iStart To $iEnd
                $sMem &= StringLeft($array[$i][$iColumn], $iStrMax) & $sZero
            Next
        EndIf
        $tSource = DllStructCreate($sBufType & StringLen($sMem) + 1 & ']')
        DllStructSetData($tSource, 1, $sMem)
        $sMem = ""
    EndIf
    ;; index data
    $tIndex = DllStructCreate('int[' & $iCount * 2 & ']')
    DllCall($h_DLL_user32, 'uint', 'CallWindowProc', 'ptr', DllStructGetPtr($tEnumProc), 'ptr', DllStructGetPtr($tSource), 'ptr', DllStructGetPtr($tIndex), 'int', $iCount, 'int', $iStart)
    ;; sort
    DllCall($h_DLL_msvcrt, 'none:cdecl', 'qsort', 'ptr', DllStructGetPtr($tIndex), 'int', $iCount, 'int', 8, 'ptr', DllStructGetPtr($tCmpWrap))
    ;DllClose($h_DLL_msvcrt)
    ;; rearrange the array by sorted index
    Local $aTmp = $array, $iRef
    If $iArrayDims = 1 Then ; 1D
        If $fDescend Then
            For $i = 0 To $iCount - 1
                $iRef = DllStructGetData($tIndex, 1, $i * 2 + 2)
                $array[$iEnd - $i] = $aTmp[$iRef]
            Next
        Else ; ascending
            For $i = $iStart To $iEnd
                $iRef = DllStructGetData($tIndex, 1, ($i - $iStart) * 2 + 2)
                $array[$i] = $aTmp[$iRef]
            Next
        EndIf
    Else ; 2D
        If $fDescend Then
            For $i = 0 To $iCount - 1
                $iRef = DllStructGetData($tIndex, 1, $i * 2 + 2)
                For $j = 0 To $iColumnMax - 1
                    $array[$iEnd - $i][$j] = $aTmp[$iRef][$j]
                Next
            Next
        Else ; ascending
            For $i = $iStart To $iEnd
                $iRef = DllStructGetData($tIndex, 1, ($i - $iStart) * 2 + 2)
                For $j = 0 To $iColumnMax - 1
                    $array[$i][$j] = $aTmp[$iRef][$j]
                Next
            Next
        EndIf
    EndIf
    Return 1
EndFunc   ;==>_ArraySortClib

Edit:

_ArraySort() can sort numerically too, but then the Array elements have to be defined as int.

Dim $aPing[5]
$aPing[0] = 90
$aPing[1] = 50
$aPing[2] = 0
$aPing[3] = 10
$aPing[4] = 6
Edited by KaFu

Share this post


Link to post
Share on other sites

If zeroes are the only issue I would just eliminate them

#include <Array.au3>
Dim $aPing[4]
$aPing[0] = 90
$aPing[1] = 50
$aPing[2] = 0
$aPing[3] = 100


Dim $Parray [1]

For $i = 0 To UBound($aPing) - 1
    If $aPing[$i] > 0 Then
        _ArrayAdd ($Parray , $aPing[$i])
    EndIf
Next

_ArrayDelete ($Parray , 0)
msgbox (0, '' , _ArrayMin ($Parray , 1 , 0))

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Share this post


Link to post
Share on other sites

@KaFu: good hint!

Thanks,

UEZ


Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

Here my 2nd idea:

#include <Array.au3>
Dim $aPing[4]
$aPing[0] = "90"
$aPing[1] = "6"
$aPing[2] = "0"
$aPing[3] = "10"

$min = Int($aPing[0])
For $i = 1 To UBound($aPing) - 1
    $value = Int($aPing[$i])
    If $value < $min And $value <> 0 Then $min = $value
Next
MsgBox(0, "Information", "Smallest number (exept zero): " & $min, 10)

Br,

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯

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