www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Remove function?

reply "seany" <seany uni-bonn.de> writes:
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
Dec 04 2013
next sibling parent reply "Brad Anderson" <eco gnuk.net> writes:
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.
Dec 04 2013
parent reply "seany" <seany uni-bonn.de> writes:
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?
Dec 04 2013
next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
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
Dec 04 2013
prev sibling parent "Brad Anderson" <eco gnuk.net> writes:
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); }
Dec 04 2013
prev sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
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
Dec 04 2013
parent reply "seany" <seany uni-bonn.de> writes:
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?
Dec 04 2013
parent reply "Chris Cain" <clcain uncg.edu> writes:
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.
Dec 04 2013
next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
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
Dec 04 2013
parent "bearophile" <bearophileHUGS lycos.com> writes:
 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
Dec 04 2013
prev sibling parent reply "seany" <seany uni-bonn.de> writes:
On Wednesday, 4 December 2013 at 23:03:10 UTC, Chris Cain wrote:

 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.
First thank you soooo much for clarification of the operation. however, i tried your solution too. this failed with the same errors as mentioned in the first post of the thread..
Dec 05 2013
parent reply "Chris Cain" <clcain uncg.edu> writes:
On Thursday, 5 December 2013 at 15:46:41 UTC, seany wrote:
 First thank you soooo much for clarification of the operation.
You're welcome.
 however, i tried your solution too. this failed with the same 
 errors as mentioned in the first post of the thread..
You sure that you don't have some other problem? file stripParTest.d: --- import std.algorithm; string stripPar(string S) { while(S[0] == '(' && S[S.length-1] == ')') { S = S[1 .. $ - 1]; } return S; } unittest { string testData = "((a)"; string result = stripPar(testData); assert(equal(result, "(a")); } --- run with: rdmd -unittest -main stripParTest.d Works fine for me.
Dec 05 2013
parent reply "seany" <seany uni-bonn.de> writes:
On Thursday, 5 December 2013 at 16:38:11 UTC, Chris Cain wrote:
 On Thursday, 5 December 2013 at 15:46:41 UTC, seany wrote:
 First thank you soooo much for clarification of the operation.
You're welcome.
 however, i tried your solution too. this failed with the same 
 errors as mentioned in the first post of the thread..
You sure that you don't have some other problem? file stripParTest.d: --- import std.algorithm; string stripPar(string S) { while(S[0] == '(' && S[S.length-1] == ')') { S = S[1 .. $ - 1]; } return S; } unittest { string testData = "((a)"; string result = stripPar(testData); assert(equal(result, "(a")); } --- run with: rdmd -unittest -main stripParTest.d Works fine for me.
I dont think i have other problems other than perhaps a bug in 2.061 dmd? By the way does your solution edit the physical memory in place, or just change the way it is pointed to? in case of the second, is there an appropriate garbage collector?
Dec 05 2013
parent "Chris Cain" <clcain uncg.edu> writes:
On Thursday, 5 December 2013 at 16:59:50 UTC, seany wrote:
 I dont think i have other problems other than perhaps a bug in 
 2.061 dmd?
I'd definitely recommend upgrading to the latest release (2.064.2) since it has lots of bug fixes since 2.061. But if your code is still saying this (your original post):
 /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:
 ...
Then you're probably using your old code somewhere. The stripPars I've suggested does not use std.algorithm.move at all.
 By the way does your solution edit the physical memory in 
 place, or just change the way it is pointed to?
It's just changing the view of the data. Ali's book covers this stuff in more detail: http://ddili.org/ders/d.en/index.html specifically: http://ddili.org/ders/d.en/slices.html
 in case of the second, is there an appropriate garbage 
 collector?
D uses garbage collection by default and it's aware of and fine with this type of thing.
Dec 05 2013