ID:2132103
 
Resolved
Strings are now compatible with the [] list index operator for read-only operation. (This is not currently documented.) Negative and zero index values, while usable in other procs, cannot currently apply here; the index must be from 1 to the string's length.
Applies to:DM Language
Status: Resolved (512.1386)

This issue has been resolved.
I literally couldn't find an open request for this.

Fifteen years ago, however, Dan, the forefather of DUNG/BYOND had said,

This would actually be pretty easy to add. It's on the list!

Fifteen years later, here we are, with DM still lacking proper string indexing.

pls
Reminder: That which would be easy for Dan may not be easy for Lummox.
To summarize this so one doesn't have to open another page to understand the FR:

Accessing characters of strings by index like stringvar[1] for the first letter, etc.
In response to MrStonedOne
MrStonedOne wrote:
To summarize this so one doesn't have to open another page to understand the FR:

Accessing characters of strings by index like stringvar[1] for the first, etc.

I honestly thought "string indexing" was self-explanatory to any experienced dev.

Nadrew wrote:
Reminder: That which would be easy for Dan may not be easy for Lummox.

Sure, no where did I imply that it would be easy for Lummox, but as he's manhandling that axial deframbulator, it'd be neat to get this in.
You may be surprised how many people don't fall under the category of 'experienced dev'
I honestly thought "string indexing" was self-explanatory to any experienced dev.

The word indexing is ambiguous. the string tree is a type of string index. in my database programmer mind, index also means a reference of finding where something is, ie, the string tree. So when you said string indexing, my mind jumped right to some way to see some sort of index number of a string inside the string tree. (you can do that by the way, with \ref and locate())

Yeah, I had to look at the original post linked to because I had no idea what was being asked... and I use Python a ton.
It took me a minute to realize what you were asking myself.

IMO, I think this probably would be easy to add. It'd have to be read-only since strings are immutable, but that's not a bad trade-off.
honestly, a better and more flexable idea might be to fix splittext() so null or "" splits the string into a list (right now it splits it into a list of n blank strings, with n being the size of the string)

Then you can join it back to a string when you are done messing with it if you do want to modify it.

Hell, maybe both!
If splittext(text,"") is producing a list of N blank strings, that's actually a bug.
mob
verb/testsplitstring()
var/text = "sddasjf;klasdjfas;ldf"
//var/list/split = (splittext(text, regex("(.)")) - splittext(text, ""))
var/list/split = splittext(text, "")
for (var/thing in split)
if (istext(thing))
world << "'[thing]'"
else
if (isnull(thing))
world << "NULL"
else if (istype(thing, /datum))
var/datum/D = thing
world << "'[D]'([D.type])"
else
world << "'[thing]'(UNKNOWN)"


the commented out code is our work around (the first split text has a null string between each letter, minusing the bad version (n null strings) from the list removed them.

The forloop was copied from another test case, so it's a bit more detailed than it needed to be, I mainly wanted something that differentiated between null and empty string
It's definitely worth reporting the splittext() issue as a bug.
In response to MrStonedOne
for this, the results of:
var/list/split = splittext(text, regex("(.)")) - splittext(text, "")
// and
var/list/split = splittext(text, regex("")) - "" + copytext(text, length(text))

are identical, though the second is a little faster, likely due to only removing a single entry from the list, rather than an entire other list.

splittext(text,"") should be faster than either if fixed, though.
In response to Lummox JR
Lummox JR wrote:
IMO, I think this probably would be easy to add. It'd have to be read-only since strings are immutable, but that's not a bad trade-off.

I'm perfectly ok with this being read-only. I'm sure it'd be tons faster than copytext or ascii2text/text2ascii.
In response to Super Saiyan X
Super Saiyan X wrote:
I'm sure it'd be tons faster than copytext or ascii2text/text2ascii.

If this is true it would be great to have.
Though, I've been wondering, if strings are not mutable, but strings *are* garbage collected (per the DM Guide), why is creating strings an issue?

Why can't something like
var/g = "string"
g[4] = "a"

just create a new string with, with g pointing to the new string post-char-replacement, "strang"? the old string would just be garbage collected if it's not being used anywhere else.
In response to Super Saiyan X
that would be "staing", because DM is 1-indexed.
In response to CrimsonVision
CrimsonVision wrote:
that would be "staing", because DM is 1-indexed.

yeah, my bad. I meant 4. I just forgot how to count.
In response to Super Saiyan X
Super Saiyan X wrote:
Though, I've been wondering, if strings are not mutable, but strings *are* garbage collected (per the DM Guide), why is creating strings an issue?

Why can't something like
...
just create a new string with, with g pointing to the new string post-char-replacement, "strang"? the old string would just be garbage collected if it's not being used anywhere else.

There are two reasons.

First, the indexing operator doesn't really have any "var reference" data for where the object being indexed comes from. It doesn't have to be just a local var g; it could be a var like src.icon_state. So there would be no way to set the result.

Second, having the value of the operand itself change is a really squirrely thing to do. Setting b[2] = x in any other language would never result in b changing its value; it's not something anyone would expect.
Had an idea.
var index = splittext(string,"")
With the second argument being null or as shown then it will split the string into every character found to allow for better workarounds.
Page: 1 2