Jump to content


StrSplit()


  • Please log in to reply
5 replies to this topic

#1 Guests

  • Guests

Posted 27 August 2011 - 07:43 AM

StrSplit(InputVar, Delimiters, OmitChars=False)This is an array version of StringSplit. Feel free to modify it.
;example 1

var = a, b, c, d, e

msgbox % StrSplit(var, "`,").3



;example 2

TestString = This is a test.

msgbox % "The 4th element is " StrSplit(TestString, A_Space, ".").4 



;example 3

Colors = red,green,blue

Arr := StrSplit(Colors, "`,")

Loop, % Arr.MaxIndex()	

    MsgBox, % "Color number " A_Index " is " Arr[A_Index] "."



StrSplit(InputVar, Delimiters, OmitChars=False) {

	StringSplit, OutPseudoArr, InputVar, % Delimiters, % OmitChars

	Result := []

	Loop, %OutPseudoArr0%

		Result.Insert(OutPseudoArr%A_Index%)

	if Result.MaxIndex()

		Return Result

	Else

		Return false

}


#2 fincs

fincs
  • Fellows
  • 1529 posts

Posted 27 August 2011 - 10:02 AM

I suggest this, which does not waste memory in creating pseudo-arrays/copying the InputVar:
StrSplit(ByRef InputVar, Delimiters="", OmitChars="")
{
   o := []
   Loop, Parse, InputVar, % Delimiters, % OmitChars
      o.Insert(A_LoopField)
   return o
}
Remember that you can pass non-vars to ByRef parameters in AHK_L.

As a side note, AutoHotkey v2-alpha has a built-in StrSplit() function.

#3 Guests

  • Guests

Posted 27 August 2011 - 10:40 AM

That's better. Thanks fincs. But I think it should return false or an empty string on failure.

#4 fincs

fincs
  • Fellows
  • 1529 posts

Posted 27 August 2011 - 11:32 AM

What failure? If InputVar is an empty string it should return an empty array.

#5 Guests

  • Guests

Posted 27 August 2011 - 12:06 PM

What failure? If InputVar is an empty string it should return an empty array.

I disagree. No results should return nothing. There is no point retrieving a copy of the string not delimited.
var1 := "red,green,blue" 
var2 := "red|green|blue"
var3 := ""

loop 3
	if (arr := StrSplit(var%A_Index%, ","))
		msgbox % "True : " arr.1		;the first element
	else
		msgbox No delimiters found.

StrSplit(ByRef InputVar, Delimiters="", OmitChars="") {
	o := []
	Loop, Parse, InputVar, % Delimiters, % OmitChars
		o.Insert(A_LoopField)		
	return o.MaxIndex() <= 1 ? "" : o
}


#6 Lexikos

Lexikos
  • Administrators
  • 8844 posts

Posted 27 August 2011 - 03:49 PM

There is no point passing an empty string to the function in the first place, right?

But there is a point to consistent behaviour.

StringSplit always "returns" a pseudo-array, with the number of items stored in OutputVar0. If given an empty string, the pseudo-array contains zero items. If given a non-empty string which doesn't contain the delimiter, the pseudo-array contains one item. Therefore, I say StrSplit() should likewise return an empty array when given an empty string, or an array containing just the input string if the delimiter isn't present.

Here's how I believe some others handle it:
[*:2uu507s7]JavaScript's split() returns an array containing at least one item.
[*:2uu507s7]VBScript's Split() returns an array; empty if given an empty string, otherwise it has at least one item.
[*:2uu507s7]Python's split() returns a list which may be empty or contain only the input string, depending on parameters.
[*:2uu507s7]PHP's explode() returns an array which may be empty or contain only the input string, depending on parameters.
[*:2uu507s7].NET's String.Split() returns an array containing at least one item.Do you notice a pattern?

Returning an empty string when the delimiter is not found reduces the usefulness of the function. For instance, when converting a comma-delimited list to an array, the result should always be an array even if the string is empty or the delimiter is not found. If StrSplit() returns an empty string in either of those cases, the caller would need to explicitly check and create its own array.

Often the simplest solution is the best. In this case, the simplest solution is to return an array with one item per iteration of the loop, which happens to be the same behaviour as StringSplit.