Simplifying array/loop function and how to make the delimiter parameter a variable?

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
magicinmath
Posts: 162
Joined: 12 Apr 2017, 23:03

Simplifying array/loop function and how to make the delimiter parameter a variable?

23 May 2017, 20:04

Looking to maybe understand a better way to do the loop and also can it be possible to use a parameter for the delimiter in StrSplit or perhaps another similar function?

Code: Select all

data:=["somedata@more here@birthday"
	,"moredata@some here@birthday"]

makearray(object_in,column){
	a:=0, object_out:=[]
	while(a<object_in.Length()){
		++a, var:=object_in[a], elementarr:=StrSplit(var,"@")
		object_out[a]:=elementarr[column]
	}
	return object_out
}

Column_n:=makearray(data,2)
*edited variable names and arrangement
Xeno234
Posts: 71
Joined: 24 Mar 2017, 18:14

Re: Simplifying array/loop function and how to make the delimiter parameter a variable?

23 May 2017, 21:20

Can be simplified a bit with a for loop.

Code: Select all

makearray(object_in,column){
	object_out := []
	for a, v in object_in
		object_out[a]:=StrSplit(v,"@")[column]
	return object_out
}
A_AhkUser
Posts: 1147
Joined: 06 Mar 2017, 16:18
Location: France
Contact:

Re: Simplifying array/loop function and how to make the delimiter parameter a variable?

23 May 2017, 21:39

Hi magicinmath,
magicinmath wrote:can it be possible to use a parameter for the delimiter in StrSplit
If you mean pass a function parameter instead of use an hard-coded string as delimiter:yes; StrSplit delimiter's parameter admits variables. You simply have to add a delimiter parameter in the definition of your function and specify it as param in the StrSplit function inside the body of your function. StrSplit delimiter's parameter also accept arrays so you even can specify more than one delimiter to be taken in consideration when the function will execute. However, in this case, you should make this parameter variadic:

Code: Select all

MyFunc(string, array*) {
Loop % (arr:=StrSplit(string, array)).length()
	MsgBox % arr[a_index]
}
MyFunc("A@B#C$D", ["@", "#", "$"]*) ; the asterisk after the final parameter marks the function as variadic
Concerning the strucure of the loop maybe, and instead of calling many times StrSplit- especially if you plan to deal with huge arrays - you could first 'stringify' your array, call StrSplit just one time and return an array wich retains only the element at index 2, 5, 8, 11, 14 --> 3n-1- magic in math! :D

Code: Select all

data:=["somedata@A@birthday", "moredata@B@birthday", "moredata@C@birthday", "moredata@D@birthday", "moredata@E@birthday"]

makearray(__arrIn, ByRef __arrOut, __delimiter:="@") {

	__str := "", __arrOut := []
	
	Loop % __arrIn.length()
		__str .= __arrIn[a_index] . "@"
	Loop % ((__arr:=StrSplit(__str, __delimiter)).length()/3)
		__arrOut.push(__arr[(3*a_index)-1]) ; https://answers.yahoo.com/question/index?qid=20080819031639AAVzhO1
	
}
makearray(data, outputArray, "@")
Loop % outputArray.length()
	MsgBox % outputArray[a_index]

Hope this helps.
my scripts
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Simplifying array/loop function and how to make the delimiter parameter a variable?

23 May 2017, 21:52

How about this:

Code: Select all

q:: ;delimiters via strings/arrays
vText := "a-b=c_d+e"
vDelim := "-"
oDelim1 := ["-"]
oDelim2 := ["-","=","_","+"]

oTemp1 := StrSplit(vText, vDelim)
oTemp2 := StrSplit(vText, oDelim1)
oTemp3 := StrSplit(vText, oDelim2)

MsgBox, % oTemp1.2 ;b=c_d+e
MsgBox, % oTemp2.2 ;b=c_d+e
MsgBox, % oTemp3.2 ;b

oDelim1 := oDelim2 := ""
oTemp1 := oTemp2 := oTemp3 := ""
return
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
magicinmath
Posts: 162
Joined: 12 Apr 2017, 23:03

Re: Simplifying array/loop function and how to make the delimiter parameter a variable?

23 May 2017, 22:11

A_AhkUser wrote:Hi magicinmath
Concerning the strucure of the loop maybe, and instead of calling many times StrSplit- especially if you plan to deal with huge arrays - you could first 'stringify' your array, call StrSplit just one time and return an array wich retains only the element at index 2, 5, 8, 11, 14 --> 3n-1- magic in math! :D
That is pretty clever. I have to wrap my head around it yet but I like the idea.

However, when I pass a variable for the delimiter, the function does not work properly.
A_AhkUser wrote:Hi magicinmath
If you mean pass a function parameter instead of use an hard-coded string as delimiter:yes; StrSplit delimiter's parameter admits variables. You simply have to add a delimiter parameter in the definition of your function and specify it as param in the StrSplit function inside the body of your function.

Code: Select all

data:=["a1@b1@c1","a2@b2@c2","a3@b3@c3"]

makearray(object_in,column,d){
	object_out := []
	for a, v in object_in
		object_out[a]:=StrSplit(v,d)[column]
	return object_out
}
Column:=makearray(data,2,@)
MsgBox, % Column[1] 			; Result is 1
edit* Nvm, the @ needs to be in quotations! I see now lol "@".

Anyways, I will considering stringify and solving the sequence for column #'s. That is a really clever and creative idea :)
A_AhkUser
Posts: 1147
Joined: 06 Mar 2017, 16:18
Location: France
Contact:

Re: Simplifying array/loop function and how to make the delimiter parameter a variable?

24 May 2017, 14:34

solving the sequence for column #'s.
Here's my attempt below so if you want to take a look:

Code: Select all

data:=["somedata@A@birthday", "moredata@B@birthday", "moredata@C@birthday", "moredata@D@birthday", "moredata@E@birthday"]

makearray(__arrIn, ByRef __arrOut, __column, __delimiter:="@") {

	__str := "", __arrOut := []
	__maxColumn := StrSplit(__arrIn[1], __delimiter).length()
	
	Loop % __arrIn.length()
		__str .= __arrIn[a_index] . __delimiter
		__str := RTrim(__str, __delimiter)
	Loop % ((__arr:=StrSplit(__str, __delimiter)).length()/__maxColumn)
		__arrOut.push(__arr[__column+(a_index-1)*__maxColumn])
	
}
Loop, 3
{
makearray(data, outputArray, a_index, "@")
Loop % outputArray.length()
	MsgBox % outputArray[a_index]

}
1, 4, 7, ...
2, 5, 8, ...
3, 6, 9, ...
- so it is rather simple: it is not one of those Millennium Prize Problems! As for me, I consider your attempt and Xeno234 one's better but I suggest this one since I was pretty sure this solution will appeals to MagicIn_Math;)

Cheers
my scripts

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: cjsmile999, doodles333, Lamron750 and 338 guests