Thread overview | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
December 04, 2013 Remove function? | ||||
---|---|---|---|---|
| ||||
Hello, I want to remove a car form a string. hence i used the remove function from std.algorithm, and i had this : string stripPar(string S) { while(S[0] == '(' && S[S.length-1] == ')') { S = S.remove(0); S = S.remove(S.length-1); } return S; } (taking help from this: http://www.digitalmars.com/d/archives/digitalmars/D/learn/std.algorithm.remove_strange_behavior_removing_items_for_the_dynamic_35713.html) I was having this error: /home/apua/Software/dmd/dmd/src/phobos/std/algorithm.d(6992): Error: template std.algorithm.move does not match any function template declaration. Candidates are: /home/apua/Software/dmd/dmd/src/phobos/std/algorithm.d(1456): std.algorithm.move(T)(ref T source, ref T target) /home/apua/Software/dmd/dmd/src/phobos/std/algorithm.d(1549): std.algorithm.move(T)(ref T source) /home/apua/Software/dmd/dmd/src/phobos/std/algorithm.d(1456): Error: template std.algorithm.move cannot deduce template function from argument types !()(dchar,dchar) /home/apua/Software/dmd/dmd/src/phobos/std/algorithm.d(7000): Error: template std.algorithm.moveAll does not match any function template declaration. Candidates are: /home/apua/Software/dmd/dmd/src/phobos/std/algorithm.d(1705): std.algorithm.moveAll(Range1, Range2)(Range1 src, Range2 tgt) if (isInputRange!(Range1) && isInputRange!(Range2) && is(typeof(move(src.front, tgt.front)))) /home/apua/Software/dmd/dmd/src/phobos/std/algorithm.d(7000): Error: template std.algorithm.moveAll(Range1, Range2)(Range1 src, Range2 tgt) if (isInputRange!(Range1) && isInputRange!(Range2) && is(typeof(move(src.front, tgt.front)))) cannot deduce template function from argument types !()(string,string) flamenco.d(233): Error: template instance std.algorithm.remove!(cast(SwapStrategy)2, string, int) error instantiating /home/apua/Software/dmd/dmd/src/phobos/std/algorithm.d(6992): Error: template std.algorithm.move does not match any function template declaration. Candidates are: /home/apua/Software/dmd/dmd/src/phobos/std/algorithm.d(1456): std.algorithm.move(T)(ref T source, ref T target) /home/apua/Software/dmd/dmd/src/phobos/std/algorithm.d(1549): std.algorithm.move(T)(ref T source) /home/apua/Software/dmd/dmd/src/phobos/std/algorithm.d(1456): Error: template std.algorithm.move cannot deduce template function from argument types !()(dchar,dchar) /home/apua/Software/dmd/dmd/src/phobos/std/algorithm.d(7000): Error: template std.algorithm.moveAll does not match any function template declaration. Candidates are: /home/apua/Software/dmd/dmd/src/phobos/std/algorithm.d(1705): std.algorithm.moveAll(Range1, Range2)(Range1 src, Range2 tgt) if (isInputRange!(Range1) && isInputRange!(Range2) && is(typeof(move(src.front, tgt.front)))) /home/apua/Software/dmd/dmd/src/phobos/std/algorithm.d(7000): Error: template std.algorithm.moveAll(Range1, Range2)(Range1 src, Range2 tgt) if (isInputRange!(Range1) && isInputRange!(Range2) && is(typeof(move(src.front, tgt.front)))) cannot deduce template function from argument types !()(string,string) flamenco.d(234): Error: template instance std.algorithm.remove!(cast(SwapStrategy)2, string, ulong) error instantiating So I changed them to string stripPar(string S) { while(S[0] == '(' && S[S.length-1] == ')') { S.remove(0); S.remove(S.length-1); } return S; } (i.e. not S = S.remove any more) But I am having the smae error again .. dmd 2.061 for 64 bit |
December 04, 2013 Re: Remove function? | ||||
---|---|---|---|---|
| ||||
Posted in reply to seany | On Wednesday, 4 December 2013 at 21:59:45 UTC, seany wrote:
> Hello, I want to remove a car form a string.
>
> hence i used the remove function from std.algorithm, and i had this :
>
> string stripPar(string S)
> {
> while(S[0] == '(' && S[S.length-1] == ')')
> {
>
> S = S.remove(0);
> S = S.remove(S.length-1);
> }
>
> return S;
> }
>
string is defined as: alias string = immutable(char)[]; This means the string contents cannot be changed because the individual characters are immutable. If you'd like to modify the string I'd use a char[] in place of string.
|
December 04, 2013 Re: Remove function? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Brad Anderson | On Wednesday, 4 December 2013 at 22:02:28 UTC, Brad Anderson wrote:
> On Wednesday, 4 December 2013 at 21:59:45 UTC, seany wrote:
>> Hello, I want to remove a car form a string.
>>
>> hence i used the remove function from std.algorithm, and i had this :
>>
>> string stripPar(string S)
>> {
>> while(S[0] == '(' && S[S.length-1] == ')')
>> {
>>
>> S = S.remove(0);
>> S = S.remove(S.length-1);
>> }
>>
>> return S;
>> }
>>
>
> string is defined as: alias string = immutable(char)[]; This means the string contents cannot be changed because the individual characters are immutable. If you'd like to modify the string I'd use a char[] in place of string.
does all the algorithms defined in std.string and std.algorithm also apply on char[] ? is there any way to force a string to become mutable?
|
December 04, 2013 Re: Remove function? | ||||
---|---|---|---|---|
| ||||
Posted in reply to seany | On 12/04/2013 01:59 PM, seany wrote: > Hello, I want to remove a car form a string. > > hence i used the remove function from std.algorithm, and i had this : > > string stripPar(string S) > { > while(S[0] == '(' && S[S.length-1] == ')') > { > > S = S.remove(0); > S = S.remove(S.length-1); > } > > return S; > A shorter alternative: import std.algorithm; string stripPar(string S) { return S.stripLeft('(').stripRight(')'); } Ali |
December 04, 2013 Re: Remove function? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Wednesday, 4 December 2013 at 22:14:18 UTC, Ali Çehreli wrote:
> On 12/04/2013 01:59 PM, seany wrote:
>> Hello, I want to remove a car form a string.
>>
>> hence i used the remove function from std.algorithm, and i had this :
>>
>> string stripPar(string S)
>> {
>> while(S[0] == '(' && S[S.length-1] == ')')
>> {
>>
>> S = S.remove(0);
>> S = S.remove(S.length-1);
>> }
>>
>> return S;
>>
>
> A shorter alternative:
>
> import std.algorithm;
>
> string stripPar(string S)
> {
> return S.stripLeft('(').stripRight(')');
> }
>
> Ali
that works, but wont the immutability imply that the above solution shall not work?
|
December 04, 2013 Re: Remove function? | ||||
---|---|---|---|---|
| ||||
Posted in reply to seany | seany:
> is there any way to force a string to become mutable?
Unlike C++, in D you can strip away immutability only if later you do not mutate the data. Between C++ and D there are some semantic differences that will bite new D programmers.
Bye,
bearophile
|
December 04, 2013 Re: Remove function? | ||||
---|---|---|---|---|
| ||||
Posted in reply to seany | On Wednesday, 4 December 2013 at 22:33:06 UTC, seany wrote:
> that works, but wont the immutability imply that the above solution shall not work?
No. Essentially stripLeft and stripRight work by shrinking a Range by calling popFront and popBack until all of the characters in question are stripped. Think of it as changing what part of the string is "pointed to" vs changing the actual data itself. Since it doesn't modify the data inside, it's fine.
There is a bug in the Ali's suggestion. It's not equivalent to what you posted.
Consider: ((a) ... what your version implies is returning "(a" ... but Ali's version would return "a"
Here's a version that does what (I think) you want:
----------
string stripPar(string S)
{
while(S[0] == '(' && S[S.length-1] == ')')
{
S = S[1 .. $ - 1];
}
return S;
}
----------
So, what this does is just changes the view of S, not the data of S. A subtle but important distinction.
|
December 04, 2013 Re: Remove function? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris Cain | Chris Cain:
> string stripPar(string S)
> {
> while(S[0] == '(' && S[S.length-1] == ')')
> {
>
> S = S[1 .. $ - 1];
> }
>
> return S;
> }
For better compatibility with Unicode it's better to use .front .back .popFront and .popBack. You can also make it pure and @safe, and take any string in input.
Not much tested:
import std.array, std.traits;
C1[] stripPar(C1, C2)(C1[] txt, in C2 open = '(', in C2 close=')')
@safe pure if (isSomeChar!C1 && isSomeChar!C2) {
while (txt.front == open && txt.back == close) {
txt.popFront;
txt.popBack;
}
return txt;
}
void main() {
import std.stdio;
"[[()()()()]"d.stripPar('[', ']').writeln;
}
Bye,
bearophile
|
December 05, 2013 Re: Remove function? | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | > C1[] stripPar(C1, C2)(C1[] txt, in C2 open = '(', in C2 close=')')
> @safe pure if (isSomeChar!C1 && isSomeChar!C2) {
> while (txt.front == open && txt.back == close) {
> txt.popFront;
> txt.popBack;
> }
>
> return txt;
> }
The next improvement step is to make it work on a Range.
Bye,
bearophile
|
December 05, 2013 Re: Remove function? | ||||
---|---|---|---|---|
| ||||
Posted in reply to seany | On Wednesday, 4 December 2013 at 22:13:52 UTC, seany wrote: > does all the algorithms defined in std.string and std.algorithm also apply on char[] ? Pretty much. If one doesn't it'd be a considered a bug. front() and popFront() defined for arrays in std.array specialize for narrow strings (that is, UTF-8 and UTF-16 encoded strings whether they are immutable(char)[] or just char[]) so they evaluate by code point. This means all algorithms that make use of ranges automatically work for either case. > is there any way to force a string to become mutable? You could just bash it over the head with a cast() but you should not do that. You can call .dup() to return a mutable copy of a string. I'm not actually sure how well remove() works with narrow strings though. Seems like it doesn't seem to like them in my quick test. Non-narrow strings work fine though. // http://dpaste.dzfl.pl/0a269245 void main() { import std.algorithm, std.stdio; dstring immutable_str = "this is an immutable string"d; dchar[] mutable_str = immutable_str.dup; mutable_str = mutable_str.remove(9, 11, 12); writeln(immutable_str); writeln(mutable_str); } |
Copyright © 1999-2021 by the D Language Foundation