Romek
Super Moderator
- Reaction score
- 963
Introduction:
A remake of one of my old snippets. (Search "Divide String" if you care). This one uses less strings, and doesn't leak as much. And this one supports multiple separators next to eachother.
Usage:
To use it, you do the following:
JASS:
local ExpString name = ExplodeString(source, separator, maxamount)
'ExpString' is a dynamic array type.
'name' is the variable name.
'source' is the string you want to explode
'separator' is the character that determine where to break the string. This will default to " " if an invalid string is specified.
And 'maxamount' is the amount of array slots that will be filled.
Note that if 'separator' is more than one character long, only the first character will be used.
Note that ExpString's will need to be destroyed after you're finished with them. They don't require nulling though.
To destroy it, just use:
JASS:
call name.destroy()
The final array slot (maxamount) will contain the rest of the string if it wasn't fully divided.
JASS:
ExplodeString("Hello, my name is Romek", " ", 5)
Will give the following results:
Code:
index[0] => "Hello,"
index[1] => "my"
index[2] => "name"
index[3] => "is"
index[4] => "Romek"
The following will give identical results:
JASS:
ExplodeString("Hello,%my%name%is%Romek", "%", 5)
As will this:
JASS:
ExplodeString("Hello,^^^^^^my^^^name^^is^^^^Romek", "^", 5)
However, changing the maximum to 2 will result in this:
Code:
index[0] => "Hello,"
index[1] => "my name is Romek"
An Example:
JASS:
// Player Chat Event.
// Sends a message to a given player
function Action takes nothing returns nothing
local ExpString result = ExplodeString(GetEventPlayerChatString(), " ", 3)
// Split the chat string into multiple words.
// "red" == "ReD", etc.
set result[0] = StringCase(result[0], false)
set result[1] = StringCase(result[1], false)
// However, we want the message to retain capitalization.
// result[0] will be the first word.
if result[0] == "-message" or result[0] == "-send" then
// We can use many alternatives to the 'command' very, very easily.
// result[1] will be the second word
if result[1] == "red" or result[1] == "1" or result[1] == GetPlayerName(Player(0)) then
// We will check if the user typed either the colour, number or name of the player
// result[2] will hold the rest of the string. In our case, this is the message.
call DisplayTimedTextToPlayer(Player(0), 0., 0., 10., result[2])
// Rinse and repeat <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin :D" loading="lazy" data-shortname=":D" />
elseif result[1] == "blue" or result[1] == "2" or result[2] == GetPlayerName(Player(1)) then
call DisplayTimedTextToPlayer(Player(1), 0., 0., 10., result[2])
endif
// Etc.. I could go up to Player(11), but I think this explains enough.
endif
// We need to destroy the ExpString as it is a dynamic array. Sorry!
call result.destroy()
// It doesn't require nulling. :]
endfunction
The Code:
JASS:
library ExplodeString
// ________________________________________
// +----------------------------------------+
// | E X P L O D E S T R I N G |
// +----------------------------------------+
// | By Romek - v3 |
// |________________________________________|
// +----------------------------------------+
struct ExpString
// Change the [10] to the maximum amount of substrings
private string array S [10]
readonly integer size
method operator [] takes integer i returns string
return .S<i>
endmethod
static method create takes string source, string separator, integer maxamount returns ExpString
local ExpString this = ExpString.allocate()
local integer i = 0
local integer last = 0
local integer first = 0
local integer length
local boolean insep = true
if maxamount < 1 then
set maxamount = 1
endif
set maxamount = maxamount - 1
if separator == "" or separator == null then
set separator = " "
else
set separator = SubString(separator, 0, 1)
endif
set .size = 0
set source = separator + source
set length = StringLength(source)
loop
exitwhen i > length
if SubString(source, i, i + 1) == separator or i == length then
if not insep then
set last = i + 1
set insep = true
if .size == maxamount then
set .S[.size ] = SubString(source, first, length)
exitwhen true
endif
set .S[.size ] = SubString(source, first, last - 1)
set .size = .size + 1
endif
elseif insep then
set insep = false
set first = i
endif
set i = i + 1
endloop
return this
endmethod
endstruct
function ExplodeString takes string source, string separator, integer maxamount returns ExpString
return ExpString.create(source, separator, maxamount)
endfunction
endlibrary</i>
.size will be the amount of array slots used.
...This must be the longest post for a snippet ever...
The Map: