digitalmars.D.learn - SlicedString Length
- Salih Dincer (75/75) Oct 20 2023 Hi,
- Salih Dincer (83/83) Oct 20 2023 Good news!
Hi, I have a string wrapper called SlicedString. What it does is very simple: Returning each piece as a slice with a assured separator at compile time by used indexOf() ! Here it is: ```d struct SlicedString(string E) { long index, back, next = -1; string data; auto length() const { import std.array : split; import std.range : walkLength; return data.split(E).walkLength; } auto popIndex(ref SlicedString!E range) { scope(exit) range.popFront(); return [range.back, range.next]; } auto elementsPos() { long[][] result; auto r = SlicedString!E(index, back, next, data); while(!r.empty) { result ~= popIndex(r); } return result; } bool empty() { return index == 0; } auto front() { return data[back..next]; } void popFront() { import std.string : find = indexOf; --index; back = ++next; next = data.find(E, next); if(next == -1) { next = data.length; } } } auto sliceOff(string E = " ")(string data) { SlicedString!E s; s.data = data; s.popFront(); return s; } // UNIT TESTS: void main() { auto str = "abc def ghi"; auto slc = str.sliceOff; auto len = slc.length; slc.index = len; import std.stdio, std.algorithm: equal; assert(slc.equal(["abc", "def", "ghi"])); // Print range: foreach(s; slc) s.write; writeln; // Print Elements Position slc.elementsPos.writeln; slc.elementsPos.writeln; } ``` The unit tests work as I want, but I find calculating the length with split() too expensive; despite walkLength()... Is there a more accurate method? Last year, Ali Çehreli told me that splitter() was also possible, but then he did something with map(). I really don't understand these! Thanks... SDB 79
Oct 20 2023
Good news! I collected them in a template with the condition of running split() once at compile time. The result seems perfect? What are your thoughts? ```d void main() { auto slc = sliceOff!"abc def ghi"; auto len = slc.length; slc.index = len; import std.stdio, std.algorithm: equal; assert(slc.equal(["abc", "def", "ghi"])); foreach(s; slc) s.write; writeln; // abcdefghi // Push Test with(slc) { string test = "jkl"; push(test); auto p = elementsPos[$ - 1]; assert(data[p[0]..p[1]] == test); } foreach(s; slc) s.write; writeln; // abcdefghijkl auto tmp = slc.dup; assert(tmp.front == "abc"); tmp.popFront; assert(slc.front == "abc"); assert(tmp.front == "def"); } template sliceOff(string STR, string SEP = " ") { auto sliceOff() { SlicedString s; s.popFront(); return s; } import std.array : split; import std.range : walkLength; enum LEN = STR.split(SEP).walkLength; struct SlicedString { long index, back, next = -1; size_t len = LEN; string data = STR; auto push(string data) { this.data ~= SEP ~ data; len++; index++; } auto elementsPos() { long[][] result; auto r = this.dup; while(!r.empty) { result ~= [r.back, r.next]; r.popFront(); } return result; } alias dup = save; auto save() { return this; } auto length() { return len; } bool empty() { return index == 0; } auto front() { return data[back..next]; } void popFront() { import std.string : find = indexOf; --index; back = ++next; next = data.find(SEP, next); if(next == -1) { next = data.length; } } } } ``` SDB 79
Oct 20 2023