AutoHotkey Community

It is currently May 27th, 2012, 1:40 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 18 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: June 22nd, 2009, 9:22 am 
Offline
User avatar

Joined: May 24th, 2009, 5:35 am
Posts: 2099
Location: Iowa, USA
Has anybody pursued (or would it even be worth while to pursue) the concept of creating VBScript Arrays using the ws4ahk lib? For example:
Code:
var = "cheese"

WS_Initialize()
WS_Exec("Dim Array(3)")
code =
(
Array(0) = "Clean Underwear"
Array(1) = "Vacuum Cleaner"
Array(2) = "New Computer"
Array(3) = %var%
)
WS_Exec(code)
WS_Eval(x, "Array(2)")
WS_Uninitialize()

msgbox % x
return

http://www.autohotkey.net/~easycom/


Last edited by jethrow on October 20th, 2009, 6:03 am, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 22nd, 2009, 12:40 pm 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7503
Location: Australia
I'd think it wouldn't be worthwile unless you're also using ws4ahk for other things. Here are two alternatives:

Code:
var = "cheese"

COM_Init()
Array := COM_CreateObject("Scripting.Dictionary")
COM_Invoke(Array, "Item", 0, "Clean Underwear")
COM_Invoke(Array, "Item", "one!", "Vacuum Cleaner") ; Not limited to numeric indices.
COM_Invoke(Array, "Item", 2, "New Computer")
COM_Invoke(Array, "Item", 3, var)
x := COM_Invoke(Array, "Item", 2)
COM_Term()

msgbox % x
return
Requires COM Standard Library.
See also Scripting.Dictionary Object as Associative Array.

Code:
var = "cheese"

A_Put(Array, _:="Clean Underwear") ; _:= because parameter is ByRef.
A_Put(Array, _:="Vacuum Cleaner")
A_Put(Array, _:="New Computer")
A_Put(Array, var, 4) ; Index is optional if appending. Note one-based (4 vs 3).
x := A_Get(Array, 2)

msgbox % x
return
Requires A_Array.

Edit:
Code:
var = "cheese"

VarSetCapacity(Array, 4*4)
NumPut(DllCall("shlwapi\StrDupA", "str", "Clean Underwear"), Array,  0)
NumPut(DllCall("shlwapi\StrDupA", "str", "Vacuum Cleaner"),  Array,  4)
NumPut(DllCall("shlwapi\StrDupA", "str", "New Computer"),    Array,  8)
NumPut(DllCall("shlwapi\StrDupA", "str", var),               Array, 12)
x := DllCall("MulDiv", "int", NumGet(Array, 12), "int", 1, "int", 1, "str")
Loop, 4
    DllCall("LocalFree", "uint", NumGet(Array, A_Index*4-4))

msgbox % "Mmm, " x "."
return
:lol:


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 22nd, 2009, 1:47 pm 
Offline
User avatar

Joined: May 24th, 2009, 5:35 am
Posts: 2099
Location: Iowa, USA
Thank you for the quick response and examples Lexikos. I have been looking into using the Scripting.Dictionary object, but I want to have multidimensional capabilities.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 22nd, 2009, 10:30 pm 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7503
Location: Australia
Since the index is a string, it can be something like x "," y:
Code:
COM_Init()
Array := COM_CreateObject("Scripting.Dictionary")
COM_Invoke(Array, "Item", "w", 2)
COM_Invoke(Array, "Item", "h", 2)
COM_Invoke(Array, "Item", "1,1", "aa")
COM_Invoke(Array, "Item", "2,1", "ab")
COM_Invoke(Array, "Item", "1,2", "ba")
COM_Invoke(Array, "Item", "2,2", "bb")
Loop % COM_Invoke(array, "Item", "h")
{
    n := A_Index
    Loop % COM_Invoke(array, "Item", "w")
        MsgBox % COM_Invoke(Array, "Item", A_Index "," n)
}
COM_Term()
return
Incidentally, it's not very different to how AutoHotkey's pseudo-arrays would be used:
Code:
Array_w = 2
Array_h = 2
Array_1_1 = aa
Array_2_1 = ab
Array_1_2 = ba
Array_2_2 = bb
Loop % Array_h
{
    n := A_Index
    Loop % Array_w
        MsgBox % Array_%A_Index%_%n%
}


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 23rd, 2009, 2:27 am 
Offline
User avatar

Joined: May 24th, 2009, 5:35 am
Posts: 2099
Location: Iowa, USA
I have been using the AHK pseudo array's, but I want to be able to pass the array to a function. I do, btw, like your concept for a 2-dimensional array using the Scripting.Dictionary object.

As long as I am getting responses :D, I have 2 questions about the Scripting.Dictionary object:
1) How would the speed compare to using an AHK array? Particularly, I am breaking the contents of a spreadsheet down into a 2-dimensional array to format the data. I would assume a AHK array would operate faster, but would the difference be significant for a spreadsheet full of data?

2) I know the Items()/Keys() functions return an array of values/keys. I've tried using these functions:
Code:
x := COM_Invoke(Array, "Items")
x := COM_Invoke(Array, "Keys")

This sets x as number (I assume a pointer to the data in memory). Is there anyway to utilize this return value in the AHK script?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 23rd, 2009, 3:45 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7503
Location: Australia
jethrow wrote:
1) How would the speed compare to using an AHK array?
I don't recall the results of my own benchmarks, but others have said that AHK arrays perform better for relatively small arrays. You'd best benchmark the two methods in the context of your own script before deciding. Some basic benchmarking advice:
  • Ensure SetBatchLines, -1 is in effect to reduce the impact other activity in the system may have on the results, and to speed up the tests.
  • If the script deals with AutoHotkey variables, ensure #NoEnv is used. Otherwise empty variables will adversely affect the results.
  • Average the result of many iterations to get an accurate reading, and run the test a few times to make sure results are consistent.
  • Use a data set typical to your usage, not something arbitrary.
Quote:
2) I know the Items()/Keys() functions return an array of values/keys.
Those functions each return a SafeArray, which isn't easy to deal with in AutoHotkey. COM_Enumerate() is much easier:
Code:
penum := COM_Invoke(Array, "_NewEnum")
While COM_Enumerate(penum, key) = 0
    text .= key "=" COM_Invoke(Array, "Item", key) "`n"
COM_Release(penum)
MsgBox % text


Note: Post modified to change member information per member request. ~ sinkfaze (07/07/2011)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 23rd, 2009, 4:23 am 
Offline

Joined: February 12th, 2007, 7:54 am
Posts: 2462
Lexikos wrote:
COM_Enumerate() is much easier:
Array isn't a COM object. You seemed confused with .NET.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 23rd, 2009, 4:28 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7503
Location: Australia
Like the code in jethrow's last post, the code in my previous post was not intended to be run standalone, but with other code that sets Array (such as my Scripting.Dictionary example):
Code:
Array := COM_CreateObject("Scripting.Dictionary")
I don't see what .NET has to do with anything (in the AutoHotkey context); IIRC .NET arrays used via COM are also represented as SafeArrays.

:roll:

Note: Post modified to change member information per member request. ~ sinkfaze (07/07/2011)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 23rd, 2009, 4:48 am 
Offline

Joined: February 12th, 2007, 7:54 am
Posts: 2462
Lexikos wrote:
Code:
Array := COM_CreateObject("Scripting.Dictionary")
Oh, I see. Sorry, I thought you meant Keys/Items array.
Quote:
I don't see what .NET has to do with anything (in the AutoHotkey context); IIRC .NET arrays used via COM are also represented as SafeArrays.
I didn't mean it in conjunction with COM. I supposed you translated some .NET code (under the assumption that .NET has a similar class as Scripting.Dictionary, _NewEnum may correspond to GetEnumerator?).


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 23rd, 2009, 5:30 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7503
Location: Australia
I searched the AutoHotkey forums for COM_Enumerate, found an example using _NewEnum and based my example on that.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 24th, 2009, 7:06 am 
Offline
User avatar

Joined: May 24th, 2009, 5:35 am
Posts: 2099
Location: Iowa, USA
Thank you for the Time & Wisdom! :D

To answer my question above, AHK arrays work faster than using the Scripting.Dictionary when breaking an Excel SS down into a 2D Array. For 8 columns & 2000 rows, a AHK array took about 500 ms, and the Scripting.Dictionary took about 2500 ms. (Approx)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 25th, 2009, 6:15 pm 
How about anybodies ideas on creating JScript Arrays using the "MSScriptControl.ScriptControl" Object. I like this because it "feels" almost like using real Array, and gives built in function options. Here's an example:
Code:
Exe(ptr, code)
{   COM_Invoke(ptr, "ExecuteStatement", code)
}

Eval(ptr, code, param = 0)
{   if param = N   ; only for sort() function - to sort numbers correctly
   {   stringreplace code, code, (), , A
      code =
      (   
      function sortNumber(a, b)
      {
      return a - b;
      }
      %code%(sortNumber)
      )
      COM_Invoke(ptr, "ExecuteStatement", code)
      return
   }   
   else
      return COM_Invoke(ptr, "Eval", code)
}

COM_Init()
A := COM_CreateObject("MSScriptControl.ScriptControl")
COM_Invoke(A, "Language", "JScript")

Exe(A, "var arr1 = new Array()")
Exe(A, "var arr2 = new Array()")
code =
(
arr1[0] = "This";
arr1[1] = "is";
arr1[2] = "an"
arr1[3] = "Array"
arr2[0] = "10";
arr2[1] = "5";
arr2[2] = "40";
arr2[3] = "25";
arr2[4] = "1000";
arr2[5] = "1";
)
Exe(A, code)

msgbox % Eval(A, "arr1.push('Additional')")
msgbox % Eval(A, "arr1.join('.')")
msgbox % Eval(A, "arr2.join('.')")
Eval(A, "arr2.sort()", "N")
msgbox % Eval(A, "arr2.join('.')")

COM_Release(A)
COM_Term()
return


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: June 25th, 2009, 6:17 pm 
:shock: Sorry, wasn't logged in


Report this post
Top
  
Reply with quote  
 Post subject: jethrow
PostPosted: June 25th, 2009, 6:18 pm 
Offline
User avatar

Joined: May 24th, 2009, 5:35 am
Posts: 2099
Location: Iowa, USA
jethrow:
:( Ok, my computer keeps logging me out when I post.

Edit - That's better! :D

Note: Post modified to change member information per member request. ~ sinkfaze (07/07/2011)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 26th, 2009, 4:52 am 
Offline

Joined: February 12th, 2007, 7:54 am
Posts: 2462
I suppose it might be useful sometimes.
Code:
COM_Init()
arr := COM_ScriptControl("var arr = new Array('This', 'is', 'a', 'test', '!');`r`n arr;", "JScript", 1)
Loop,   % COM_Invoke(arr, "length")
MsgBox, % COM_Invoke(arr, A_Index-1)
COM_Release(arr)
COM_Term()


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 18 posts ]  Go to page 1, 2  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: No registered users and 2 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group