Sign in to follow this  
Followers 0
NearValue

Get the nearest Value from an Array with a given number?

16 posts in this topic

Greetings AutoIT community!

I have a simple code here that get the exact value from a given Array, now my problem is what if the exact value does not exist? What would be the code to search the nearest value of "$GivenNumber" from the said Array?

Thanks in Advance! ;)

DIM $aRecords1[10]

$GivenNumber = 3

For $x = 1 to $aRecords1[0]


     If $PP < $GivenNumberThen


     ElseIf $PP = $GivenNumberThen

          MSGBOX(0,"Exact Value", $PP)

     Else

          $LOW = "NO"

     EndIf


Next

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

DIM $aRecords1[10]
$GivenNumber = 3
$sLast = ""
$sCurrent = 999999999 ; more elegant ways are possible :)
$iClosest = ""
For $x = 1 to $aRecords1[0]
$sLast = $sCurrent
$sCurrent = Abs ( $aRecords1[$x]- $GivenNumber)
If $sCurrent < $sLast Then $iClosest = $x
Next

this will work.

Edited by jdelaney

IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window.

Share this post


Link to post
Share on other sites

Try to use Local or Global exclusively instead of Dim


_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 04/09/2015

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

How about this? Not test & does anyone have the link to online help all i have is this and it does not show UDFs like _arraydisplay() -->> http://www.autoitscript.com/autoit3/docs/functions.htm

<autoit>

For $x = 1 to $aRecords1[0]

If $aRecords1[$x] = $GivenNumber Then

MsgBox('',$aRecords1[$x] & '=' & $GivenNumber,'MATCH')

ExitLoop

EndIf

$sLast = $sCurrent

$sCurrent = Abs ( $aRecords1[$x] - $GivenNumber)

If $sCurrent < $sLast Then $iClosest = $aRecords1[$x]

Next

</autoit>

PS i borrowed all the code from jdelaney

EDIT - updated index in first IF statement from 0 to $x

Edited by nitekram

All by me:

"Sometimes you have to go back to where you started, to get to where you want to go." 

"Everybody catches up with everyone, eventually" 

"As you teach others, you are really teaching yourself."

From my dad

"Do not worry about yesterday, as the only thing that you can control is tomorrow."

 

WindowsError.gif

WIKI | Tabs; | Arrays; | Strings | Wiki Arrays | How to ask a Question | Forum Search | FAQ | Tutorials | Original FAQ | ONLINE HELP | UDF's Wiki | AutoIt PDF

AutoIt Snippets | Multple Guis | Interrupting a running function | Another Send

StringRegExp | StringRegExp Help | RegEXTester | REG TUTOR | Reg TUTOT 2

AutoItSetOption | Macros | AutoIt Snippets | Wrapper | Autoit  Docs

SCITE | SciteJump | BB | MyTopics | Programming | UDFs | AutoIt 123 | UDFs Form | UDF

Learning to script | Tutorials | Documentation | IE.AU3 | Games? | FreeSoftware | Path_Online | Core Language

Programming Tips

Excel Changes

ControlHover.UDF

GDI_Plus

Draw_On_Screen

GDI Basics

GDI_More_Basics

GDI Rotate

GDI Graph

GDI  CheckExistingItems

GDI Trajectory

Replace $ghGDIPDll with $__g_hGDIPDll

DLL 101?

Array via Object

GDI Swimlane

GDI Plus French 101 Site

GDI Examples UEZ

GDI Basic Clock

GDI Detection

Ternary operator

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

oh. let me try

Ng1-Nf3 code first.

Edited by NearValue

Share this post


Link to post
Share on other sites

outside of the loop, add the msgbox:

MsgBox(0,"closest",$avArray1[$iClosest])

you are only setting the array variable which is closest, you then need to use that relative to the array to return the value


IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window.

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

also, if you are creating the array yourself, then it is probably 0 based, so switch out the for loop with:

For $x = 0 To UBound( $avArray1) - 1
Edited by jdelaney

IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window.

Share this post


Link to post
Share on other sites

The Array values are below:

12.001

6.001

4.001

3

$GivenNumber = 1

$sLast = ""
$sCurrent = 12.001 ;max number to search
$iClosest = ""

For $x = 0 To UBound( $avArray1) - 1

     If $avArray1[$x] = $GivenNumber Then
          MsgBox('',$avArray1[$x] & '=' & $GivenNumber,'MATCH')
          ExitLoop
     EndIf

     $sLast = $sCurrent
     $sCurrent = Abs ( $avArray1[$x] - $GivenNumber)

     If $sCurrent < $sLast Then $iClosest = $avArray1[$x]

     Next

     MsgBox(0,"closest",$avArray1[$iClosest])

But the code shows 6.001 as the closest instead of 3? Can't find the bug here ;)

Share this post


Link to post
Share on other sites

Here a small different approach.

#include <Array.au3>
Global $aNumbers[10]
For $i = 0 To UBound($aNumbers) - 1
    $aNumbers[$i] = Round(Random(0, 500, 0), 2)
Next

ConsoleWrite(SearchNearest($aNumbers, 111.11) & @LF)
_ArrayDisplay($aNumbers)

Func SearchNearest($aArray, $fNumber)
    _ArraySort($aArray)
    Local $i = 0, $ret, $dx, $dx_old = 0x7FFFFFF
    While True
        $dx = Abs($aArray[$i] - $fNumber)
        If $dx_old >= $dx Then
            $dx_old = $dx
            $ret = $i
        Else
            ExitLoop
        EndIf
        $i += 1
    WEnd
    Return $aArray[$ret]
EndFunc

Br,

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

also, if you are creating the array yourself, then it is probably 0 based, so switch out the for loop with:

For $x = 0 To UBound( $avArray1) - 1

Two thumbs up for this!

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

#include <Array.au3>
$GivenNumber = 1
dim $avArray1[3]= [12.001,6.001,4.001]
$sLast = ""
$sCurrent = _ArrayMax ( $avArray1 ) ;max number to search
$iClosest = ""
For $x = 0 To UBound( $avArray1) - 1
     If $avArray1[$x] = $GivenNumber Then
          $iClosest = $x
          ExitLoop
     EndIf
     $sLast = $sCurrent
     $sCurrent = Abs ( $avArray1[$x] - $GivenNumber)
     If $sCurrent < $sLast Then $iClosest = $x
Next
MsgBox(0,"closest",$avArray1[$iClosest])

Edited by jdelaney

IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window.

Share this post


Link to post
Share on other sites

#include <Array.au3>
$GivenNumber = 1
dim $avArray1[3]= [12.001,6.001,4.001]
$sLast = ""
$sCurrent = _ArrayMax ( $avArray1 ) ;max number to search
$iClosest = ""
For $x = 0 To UBound( $avArray1) - 1
     If $avArray1[$x] = $GivenNumber Then
          $iClosest = $x
          ExitLoop
     EndIf
     $sLast = $sCurrent
     $sCurrent = Abs ( $avArray1[$x] - $GivenNumber)
     If $sCurrent < $sLast Then $iClosest = $x
Next
MsgBox(0,"closest",$avArray1[$iClosest])

Ayt! Good Game jdelaney! Woot!

Share this post


Link to post
Share on other sites

it works, but it's dirty, and not re-usable. @UEZ is a better approach, and you may then re-use it...all about modularity.


IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window.

Share this post


Link to post
Share on other sites

Code now works like a charm ^^^^^^^^^__________________^^^^^^^^^^^^

Share this post


Link to post
Share on other sites

I think that's right!

Share this post


Link to post
Share on other sites

Without #include files.

Local $GivenNum = 7
Local $Array[5] = ["zx", 4.001, 12, 6.001, "ab"]

Local $iIndex = _ArrayGetClosestValue($Array, $GivenNum)
MsgBox(0, "closest to " & $GivenNum, "Number " & $Array[$iIndex] & " closest in array with index " & $iIndex & ".")


; Returns: The array index whose difference between the array value and the given number is the lowest.
Func _ArrayGetClosestValue(ByRef $aArray, $GivenNumber)
    Local $Diff = Abs($aArray[0] - $GivenNumber)
    Local $iClosest = 0

    For $x = 1 To UBound($aArray) - 1
        If (Number($aArray[$x]) <> "") And (Abs($aArray[$x] - $GivenNumber) < $Diff) Then
            $Diff = Abs($aArray[$x] - $GivenNumber)
            $iClosest = $x
        EndIf
    Next
    Return $iClosest
EndFunc   ;==>_ArrayGetClosestValue

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