Sign in to follow this  
Followers 0
SoulBlade

Return 5 highest values from Multiple dimensional array

7 posts in this topic

Hi!

Im trying to find a way to retrieve the 5 highest values from a multiple dimensional array, so far without success.

In this particular script i need to get 5 process names with the highest memory use. The names and memory results should be created without using _ArrayDisplay.

Thanks your help!

:)

CODE
AutoItSetOption("TrayIconHide", 1)

#include <GUIConstants.au3>

#include <array.au3> ; for _ArrayDisplay()

$avRET = _ProcessListProperties()

;_ArraySort( $avRET,1,0)

$Gui=GUICreate("Processes",514, 330)

GUICtrlCreateLabel($avRET[1][0], 100, 154, 200, 14,$SS_LEFT)

GUICtrlCreateLabel($avRET[1][7], 360, 154, 200, 14,$SS_LEFT)

;_ArrayDisplay($avRET, "Debug: $avProcs, @error = " & @error)

GUISetState ()

Do

$msg = GUIGetMsg()

Until $msg = $GUI_EVENT_CLOSE

;===============================================================================

; Function Name: _ProcessListProperties()

; Description: Get various properties of a process, or all processes

; Call With: _ProcessListProperties( [$Process [, $sComputer]] )

; Parameter(s): (optional) $Process - PID or name of a process, default is all

; (optional) $sComputer - remote computer to get list from, default is local

; Requirement(s): AutoIt v3.2.4.9+

; Return Value(s): On Success - Returns a 2D array of processes, as in ProcessList()

; with additional columns added:

; [0][0] - Number of processes listed (can be 0 if no matches found)

; [1][0] - 1st process name

; [1][1] - 1st process PID

; [1][2] - 1st process Parent PID

; [1][3] - 1st process owner

; [1][4] - 1st process priority (0 = low, 31 = high)

; [1][5] - 1st process executable path

; [1][6] - 1st process CPU usage

; [1][7] - 1st process memory usage

; ...

; [n][0] thru [n][7] - last process properties

; On Failure: Returns array with [0][0] = 0 and sets @Error to non-zero (see code below)

; Author(s): PsaltyDS at http://www.autoitscript.com/forum

; Notes: If a numeric PID or string process name is provided and no match is found,

; then [0][0] = 0 and @error = 0 (not treated as an error, same as ProcessList)

; This function requires admin permissions to the target computer.

; All properties come from the Win32_Process class in WMI.

;===============================================================================

Func _ProcessListProperties($Process = "", $sComputer = ".")

Local $sUserName, $sMsg, $sUserDomain, $avProcs

If $Process = "" Then

$avProcs = ProcessList()

Else

$avProcs = ProcessList($Process)

EndIf

; Return for no matches

If $avProcs[0][0] = 0 Then Return $avProcs

; ReDim array for additional property columns

ReDim $avProcs[$avProcs[0][0] + 1][8]

; Connect to WMI and get process objects

$oWMI = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $sComputer & "\root\cimv2")

If IsObj($oWMI) Then

; Get collection of all processes from Win32_Process

$colProcs = $oWMI.ExecQuery ("select * from win32_process")

If IsObj($colProcs) Then

; For each process...

For $oProc In $colProcs

; Find it in the array

For $n = 1 To $avProcs[0][0]

If $avProcs[$n][1] = $oProc.ProcessId Then

; [n][2] = Parent PID

$avProcs[$n][2] = $oProc.ParentProcessId

; [n][3] = Owner

If $oProc.GetOwner ($sUserName, $sUserDomain) = 0 Then $avProcs[$n][3] = $sUserDomain & "\" & $sUserName

; [n][4] = Priority

$avProcs[$n][4] = $oProc.Priority

; [n][5] = Executable path

$avProcs[$n][5] = $oProc.ExecutablePath

ExitLoop

EndIf

Next

Next

Else

SetError(2) ; Error getting process collection from WMI

EndIf

; Get collection of all processes from Win32_PerfFormattedData_PerfProc_Process

; Have to use an SWbemRefresher to pull the collection, or all Perf data will be zeros

Local $oRefresher = ObjCreate("WbemScripting.SWbemRefresher")

$colProcs = $oRefresher.AddEnum ($oWMI, "Win32_PerfFormattedData_PerfProc_Process" ).objectSet

$oRefresher.Refresh

; Time delay before calling refresher

Local $iTime = TimerInit()

Do

Sleep(10)

Until TimerDiff($iTime) > 100

$oRefresher.Refresh

; Get PerfProc data

For $oProc In $colProcs

; Find it in the array

For $n = 1 To $avProcs[0][0]

If $avProcs[$n][1] = $oProc.IDProcess Then

$avProcs[$n][6] = $oProc.PercentProcessorTime

$avProcs[$n][7] = $oProc.WorkingSet

ExitLoop

EndIf

Next

Next

Else

SetError(1) ; Error connecting to WMI

EndIf

; Return array

Return $avProcs

EndFunc ;==>_ProcessListProperties

Share this post


Link to post
Share on other sites



You will need to look at the For Next Loop so you can keep returning values.

You are right but the problem is that i dont know how to sort the array.

Maybe the solution is creating a sub array?!?

:)

Share this post


Link to post
Share on other sites

This example from the help file should help you.

#include <Array.au3>

Dim $avArray[10]
$avArray[0] = "JPM"
$avArray[1] = "Holger"
$avArray[2] = "Jon"
$avArray[3] = "Larry"
$avArray[4] = "Jeremy"
$avArray[5] = "Katrijn"
$avArray[6] = "Cyberslug"
$avArray[7] = "Nutster"
$avArray[8] = "Tylo"
$avArray[9] = "JdeB"

_ArrayDisplay( $avArray, "Unsorted" )
_ArraySort( $avArray)
_ArrayDisplay( $avArray, "Sort Ascending" )
_ArraySort( $avArray,1)
_ArrayDisplay( $avArray, "Sort Decending" )

; Example sort Array created with StringSplit.
$avArray = StringSplit("b,d,c,w,a,e,s,r,x,q",",")
_ArrayDisplay( $avArray, "UnSorted" )
_ArraySort( $avArray,0,1,5)  ; sort first 5 entries
_ArrayDisplay( $avArray, "Sort first 5 entries" )
_ArraySort( $avArray,0,1)  ; sort and start at 1.. skip array[0]
_ArrayDisplay( $avArray, "Sorted starting at 1" )
_ArraySort( $avArray,1,1)  ; sort and start at 1.. skip array[0]
_ArrayDisplay( $avArray, "Sorted Desc starting at 1" )

; Demonstration difference Alpha-numeric and Numeric sorting
Dim $avArray = StringSplit("2|4|7|1|-9|5","|")
_ArrayDisplay( $avArray, "Unsorted" )
_ArraySort( $avArray,1,1)
_ArrayDisplay( $avArray, "Alpha numeric Sorted Descending" )
;Convert Array entries to numeric values
For $x = 1 To UBound($avArray) -1
    $avArray[$x] = Number($avArray[$x])
Next
_ArraySort( $avArray,1,1) 
_ArrayDisplay( $avArray, "Numeric Sorted Descending" )
Exit

Agreement is not necessary - thinking for one's self is!

My-Colors.jpg

cuniform2.gif

Share this post


Link to post
Share on other sites

This example from the help file should help you.

#include <Array.au3>

Dim $avArray[10]
$avArray[0] = "JPM"
$avArray[1] = "Holger"
$avArray[2] = "Jon"
$avArray[3] = "Larry"
$avArray[4] = "Jeremy"
$avArray[5] = "Katrijn"
$avArray[6] = "Cyberslug"
$avArray[7] = "Nutster"
$avArray[8] = "Tylo"
$avArray[9] = "JdeB"

_ArrayDisplay( $avArray, "Unsorted" )
_ArraySort( $avArray)
_ArrayDisplay( $avArray, "Sort Ascending" )
_ArraySort( $avArray,1)
_ArrayDisplay( $avArray, "Sort Decending" )

; Example sort Array created with StringSplit.
$avArray = StringSplit("b,d,c,w,a,e,s,r,x,q",",")
_ArrayDisplay( $avArray, "UnSorted" )
_ArraySort( $avArray,0,1,5)  ; sort first 5 entries
_ArrayDisplay( $avArray, "Sort first 5 entries" )
_ArraySort( $avArray,0,1)  ; sort and start at 1.. skip array[0]
_ArrayDisplay( $avArray, "Sorted starting at 1" )
_ArraySort( $avArray,1,1)  ; sort and start at 1.. skip array[0]
_ArrayDisplay( $avArray, "Sorted Desc starting at 1" )

; Demonstration difference Alpha-numeric and Numeric sorting
Dim $avArray = StringSplit("2|4|7|1|-9|5","|")
_ArrayDisplay( $avArray, "Unsorted" )
_ArraySort( $avArray,1,1)
_ArrayDisplay( $avArray, "Alpha numeric Sorted Descending" )
;Convert Array entries to numeric values
For $x = 1 To UBound($avArray) -1
    $avArray[$x] = Number($avArray[$x])
Next
_ArraySort( $avArray,1,1) 
_ArrayDisplay( $avArray, "Numeric Sorted Descending" )
Exit

I've already tryied to use that command and also the help file but i cant pass the error: "Array variable has incorrect number of subscripts or subscript dimension range exceeded."

Please just try my code.

Thanks!

Share this post


Link to post
Share on other sites

Hi,

Does this work for you?

$avRET = _ProcessListProperties()
For $x = 1 To UBound($avRET) -1
    $avRET[$x][7] = Number($avRET[$x][7])
Next
_ArraySort($avRET, 1, 0, -1, UBound($avRET,2), 7)

_ArrayDisplay($avRET)
Best, Randall

Share this post


Link to post
Share on other sites

Hi,

Does this work for you?

$avRET = _ProcessListProperties()
For $x = 1 To UBound($avRET) -1
    $avRET[$x][7] = Number($avRET[$x][7])
Next
_ArraySort($avRET, 1, 0, -1, UBound($avRET,2), 7)

_ArrayDisplay($avRET)
Best, Randall
That's a simple and efective solution!

There's no way i could solve this alone.

Many thanks!

:)

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