String Slicing?

The LEFT, RIGHT, and MID functions seem a little clunky compared to say… Python string slicing. Is there any way via operator overloading or something that perhaps a simpler string slicing syntax could be created? e.g. FirstTwoChars = MyString[:2] LastFourChars = MyString[-4:] MIddlePart = MyString[8:12]

Sure. MyString.Left(2), MyString.Right(4), and MyString.Mid(9, 4).

@Robert Bednar , I guess you’re one of those people who think curly braces or indentation are vast improvements over “Then” and “End”.

I can also vouch for the performance of the Split, Left, Right, and Mid functions WRT Python’s string handling, especially if you don’t need to deal with encodings and can use the SplitB, LeftB, RightB, and MidB byte-oriented variants. In fact, if you’re trying to get the Python performance, always use the B-variants when dealing with simple strings:

AscB, ChrB, InStrB, LeftB, LenB, MidB, RightB

To clarify - when I say simple strings, I mean data segments where you are concerned about each byte rather than the unicode context. It may not be “strings” per se, but the “B” variants allow you to work on a single, 8bit character/byte within the data and is a bit (pun intended) easier than working with MemoryBlocks.

You could use Extension Methods and Pairs to make your own Slice method to have code that looks like this:

Dim myString As String = "She sells seashells by the seashore."

Dim firstTwoChars As String = myString.Slice(2) // Sh
Dim lastTwoChars As String = myString.Slice(-2) // e.
Dim middlePart As String = myString.Slice(11:9) // seashells
Dim middlePart2 As String = myString.Slice(-9:3) // sea

General idea with no error handling:

Public Function Slice(Extends s As String, p As Pair) as String Dim start As Integer If p.Left.IntegerValue >= 0 Then start = p.Left.IntegerValue Else start = s.Len + p.Left.IntegerValue + 1 End If Return s.Mid(start, p.Right.IntegerValue) End Function

Public Function Slice(Extends s As String, startEnd As Integer) as String If startEnd >= 0 Then Return s.Left(startEnd) Else Return s.Right(-startEnd) End If End Function

and “simpler” is in the eye of the beholder… I personally do not find that syntax to be intutitve at all…

And while Pauls idea will work (not the exact syntax you specified)… be in mind it adds another lay of computation.

I agree with Dave - the use of the

FirstTwoChars = MyString.LeftB(2) LastFourChars = MyString.RightB(4) MiddlePart = MyString.MidB(8,12)

Is just as sensible as the Python original.

Oooo curly braces…gotta love 'em. I work with MultiValue databases (E.G. Universe, Reality, etc) and Records are presented as multi-dimensional dynamic arrays. These types of databases can be very flexible and efficient. One of the DB’s I work with supports (in theory) records with 2 billion attributes (think columns in SQL). Each column can have 2 billion Multivalues, each Multi-Value can have two billion Subvalues…and each sub value can hold up to 2 GB of data. That’s just in one record. Who would be crazy enough to actually do something like that? Anyway… you can retrieve and assign elements in a record using an array-like syntax. Example: LastBackUpDate = MyRecord<3,4> (attribute 3 multivalue 4) and if I want to store a piece of data I can say MyRecord<3,4> = “Xojo”. So Let’s say your record is a delimited string like “Every]Good]Boy]Does]Fine” and I want to replace “Boy” with “Girl”. In a Multivalue database I just say rec<3> = “Girl” — That’s it. In Xojo I’ll need to do some “nth field” work and some substring concatenations. All good and well…but I’d like to use the familiar multivalue rec<3> syntax. I like Paul’s suggestion of using extension methods and pairs. I can probably get my syntax down to rec.get(3,4) and rec.set(3,4) to perform all the nth field and string concatenations in my “get” and “set” methods. I used pythonic string slicing as an example familiar to more programmers than multivalue DB. I was originally wondering if I could overload the array or equality operators “< >” to do my bidding. Sorry I wasn’t more specific about what I’m actually trying to do.

Why not just use the array and reference the parts by index?

dim rec as string = GetRec // "Every]Good]Boy]Does]Fine"

// Process the data like ...
dim data() as string = rec.Split( "]" )
data( 2 ) = "Girl" // zero-based

// All done processing
rec = join( data, "]" ) // "Every]Good]Girl]Does]Fine"
StoreRec rec

Kem’s suggestion certainly possible The multi-dimensional component means I’d need a multi-dimensional array – which isn’t really a problem… but if you have a 3 multivalues in data(1,1) data(1,2) and data(1,3) you would normally retrieve the “sub-array” when you ask for data( 1 ). You actually kind of have an array of arrays of arrays. Plus… you should be able to insert elements into the arrays. This may be supported in Xojo array handling – I didn’t look it up. A typical record is more complex than my example of course. and there are " correlative" values and other unusual Multivalue database concepts that don’t exactly lend themselves well to the array model. Imagine you have an “empty” record – I want data( 23) = “Hello”. I may…or may not define some of the other positions later. They are treated automatically as null fields. So whenever I’ll probably have to do some extra work if I want to set a position higher than the size of my current item…unless I used fixed dimensioned arrays. That starts to gobble up memory and add more overhead into individual record handling.

Still it may be well enough my purposes. I expect that there is significant overhead in creating and destroying arrays. Acceptable for something like a web service where you process a record and your are done - but I anticipate working on result sets with millions of records. I figure I can do the coding…but it would be really slick if I could overload the bracket operators see that when I create an item of type “multivalve” I could use [1,3] and define exactly what that means.

That’s why in my example I wanted to know if I could say…overload [ ] to do something else…something like string slicing.
Dim x as String.
x = “every]good]boy]does]fine”
x[2] = “bad”

The [ ] is probably not defined on a string type variable…so maybe I could define it to do my bidding.
instead… I have to use…

x.slice[2] = “bad”

actually…I’d rather use ‘<’ and ‘>’.

x<2> = “bad”

result = x<5>

that sort of thing. If I can “extend” the string class into my own class (mv_string) where a variable number of parameters (x, y, z) are understood and operate on my mv_string but also inherit all the usual string methods that would be great.

If you make your own class, check out the Operator_Subscript method. That would let you do something like MyVar(2) and have it pull out a particular array item.

As for variable parameters, look at ParamArray.

You cannot make it so [ ] or < > work though.