digitalmars.D.learn - Need help: Return reference slice
- advibm (24/24) Oct 29 2014 Hello,
- bearophile (7/14) Oct 29 2014 To do this you don't need to return a ref slice. A slice
- advibm (6/22) Oct 29 2014 Thank you for your fast answer.
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (28/50) Oct 29 2014 There are pretty useful std.algorithm functions for searching:
- Steven Schveighoffer (17/39) Oct 30 2014 How I would do it:
- bearophile (4/9) Oct 30 2014 I think there it's better to use "auto" instead of "long".
- Steven Schveighoffer (3/10) Oct 30 2014 Sure, I didn't touch OP's function body, just the signature.
- advibm (3/3) Oct 30 2014 Thank you very much for your additions.
Hello, I would like to create a D function that returns a slice of a string. This slice shall be a reference to a part of the string argument. Is this generally possible in D? This is the function: auto ref betweenTwoStrings(T)(inout T src, string start, string end) { long a = src.countUntil(start); if (a < 0) return src; // null a += start.length; long b = src[a..$].countUntil(end); if (b < 0) return src; // null b += a; return src[a..b]; } I would like to have something like that: char[] buf; // already filled array char[] partOfBuf = betweenTwoStrings(buf, "START", "END"); partOfBuf[0] = 'a'; // THIS should also change the 'buf' variable assert(buf[0] == 'a'); Thanks for your help
Oct 29 2014
advibm:I would like to have something like that: char[] buf; // already filled array char[] partOfBuf = betweenTwoStrings(buf, "START", "END"); partOfBuf[0] = 'a'; // THIS should also change the 'buf' variable assert(buf[0] == 'a'); Thanks for your helpTo do this you don't need to return a ref slice. A slice suffices. But D strings/wstrings/dstrings are made of immutable chars, so you can't modify them. So you need to work with char[] or dchar[] or wchar[]. Bye, bearophile
Oct 29 2014
On Wednesday, 29 October 2014 at 19:54:45 UTC, bearophile wrote:advibm:Thank you for your fast answer. I am embarrased but my code already works as expected. I made a mistake when I wanted to change the partOfBuf variable. I wrote: partOfBuf = replacedArray; But I had to write partOfBuf[0..$] = replacedArray.I would like to have something like that: char[] buf; // already filled array char[] partOfBuf = betweenTwoStrings(buf, "START", "END"); partOfBuf[0] = 'a'; // THIS should also change the 'buf' variable assert(buf[0] == 'a'); Thanks for your helpTo do this you don't need to return a ref slice. A slice suffices. But D strings/wstrings/dstrings are made of immutable chars, so you can't modify them. So you need to work with char[] or dchar[] or wchar[]. Bye, bearophile
Oct 29 2014
On 10/29/2014 12:50 PM, advibm wrote:Hello, I would like to create a D function that returns a slice of a string. This slice shall be a reference to a part of the string argument. Is this generally possible in D? This is the function: auto ref betweenTwoStrings(T)(inout T src, string start, string end) { long a = src.countUntil(start); if (a < 0) return src; // null a += start.length; long b = src[a..$].countUntil(end); if (b < 0) return src; // null b += a; return src[a..b]; } I would like to have something like that: char[] buf; // already filled array char[] partOfBuf = betweenTwoStrings(buf, "START", "END"); partOfBuf[0] = 'a'; // THIS should also change the 'buf' variable assert(buf[0] == 'a'); Thanks for your helpThere are pretty useful std.algorithm functions for searching: import std.algorithm; import std.traits; import std.array; C[] betweenTwoStrings(C)(C[] src, string start, string end) if (isSomeChar!C) { if (src.findSkip(start)) { auto found = src.findSplitBefore(end); // Just for readability: auto needleAndAfter = found[1]; if (!needleAndAfter.empty) { auto beforeNeedle = found[0]; return beforeNeedle; } } return (C[]).init; } void main() { char[] buf; buf ~= "prefixSTARTactual partENDpostfix"; char[] partOfBuf = betweenTwoStrings(buf, "START", "END"); partOfBuf[] = 'a'; assert(buf == "prefixSTARTaaaaaaaaaaaENDpostfix"); } Ali
Oct 29 2014
On 10/29/14 3:50 PM, advibm wrote:Hello, I would like to create a D function that returns a slice of a string. This slice shall be a reference to a part of the string argument. Is this generally possible in D? This is the function: auto ref betweenTwoStrings(T)(inout T src, string start, string end) { long a = src.countUntil(start); if (a < 0) return src; // null a += start.length; long b = src[a..$].countUntil(end); if (b < 0) return src; // null b += a; return src[a..b]; } I would like to have something like that: char[] buf; // already filled array char[] partOfBuf = betweenTwoStrings(buf, "START", "END"); partOfBuf[0] = 'a'; // THIS should also change the 'buf' variable assert(buf[0] == 'a'); Thanks for your helpHow I would do it: inout(T)[] betweenTwoStrings(T, U, V)(inout(T)[] src, const(U)[] start, const(V)[] end) if(allSatisfy!(isSomeChar, T, U, V)) { long a = src.countUntil(start); if (a < 0) return src; // null a += start.length; long b = src[a..$].countUntil(end); if (b < 0) return src; // null b += a; return src[a..b]; } This should accept any kind of strings, in any constancy for all the parameters, yet guarantee it does not change any data in any of them. -Steve.
Oct 30 2014
Steven Schveighoffer:long a = src.countUntil(start); if (a < 0) return src; // null a += start.length; long b = src[a..$].countUntil(end);I think there it's better to use "auto" instead of "long". Bye, bearophile
Oct 30 2014
On 10/30/14 11:06 AM, bearophile wrote:Steven Schveighoffer:Sure, I didn't touch OP's function body, just the signature. -Stevelong a = src.countUntil(start); if (a < 0) return src; // null a += start.length; long b = src[a..$].countUntil(end);I think there it's better to use "auto" instead of "long".
Oct 30 2014
Thank you very much for your additions. I am still new to D so I am glad to see solutions from experienced D programmers.
Oct 30 2014