Thread overview | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
October 29, 2014 Need help: Return reference slice | ||||
---|---|---|---|---|
| ||||
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 |
October 29, 2014 Re: Need help: Return reference slice | ||||
---|---|---|---|---|
| ||||
Posted in reply to advibm | 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 help
To 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
|
October 29, 2014 Re: Need help: Return reference slice | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Wednesday, 29 October 2014 at 19:54:45 UTC, bearophile wrote:
> 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 help
>
> To 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
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.
|
October 29, 2014 Re: Need help: Return reference slice | ||||
---|---|---|---|---|
| ||||
Posted in reply to advibm | 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 help There 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 |
October 30, 2014 Re: Need help: Return reference slice | ||||
---|---|---|---|---|
| ||||
Posted in reply to advibm | 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 help
How 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.
|
October 30, 2014 Re: Need help: Return reference slice | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | 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
|
October 30, 2014 Re: Need help: Return reference slice | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On 10/30/14 11:06 AM, bearophile wrote:
> 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".
Sure, I didn't touch OP's function body, just the signature.
-Steve
|
October 30, 2014 Re: Need help: Return reference slice | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | Thank you very much for your additions. I am still new to D so I am glad to see solutions from experienced D programmers. |
Copyright © 1999-2021 by the D Language Foundation