Thread overview | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
December 31, 2013 Task to throw away string parts, use joiner and splitter not very successful | ||||
---|---|---|---|---|
| ||||
Hello, i have string like "this.is.a.string" and want to throw away some parts separated by dots, here is first attempt: name = "this.is.a.string"; // <-- want to make "this.is.a" from this auto nameparts = splitter(name, '.'); auto name1 = joiner(nameparts[0 .. $-1], '.'); And got this error: "Error: Result cannot be sliced with []" So, kinda fixed it (correct way?): name = "this.is.a.string"; auto nameparts = splitter(name, '.').array; auto name1 = joiner(nameparts[0 .. $-1], '.'); got this: Error: template std.algorithm.joiner does not match any function template declaration. Candidates are: /usr/include/dmd/phobos/std/algorithm.d(2846): std.algorithm.joiner(RoR, Separator)(RoR r, Separator sep) if (isInputRange!RoR && isInputRange!(ElementType!RoR) && isForwardRange!Separator && is(ElementType!Separator : ElementType!(ElementType!RoR))) Stuck here, thank you for any help. |
December 31, 2013 Re: Task to throw away string parts, use joiner and splitter not very successful | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dfr | On Tuesday, 31 December 2013 at 20:49:55 UTC, Dfr wrote:
> Hello, i have string like "this.is.a.string" and want to throw away some parts separated by dots, here is first attempt:
>
> name = "this.is.a.string"; // <-- want to make "this.is.a" from this
> auto nameparts = splitter(name, '.');
> auto name1 = joiner(nameparts[0 .. $-1], '.');
>
> And got this error: "Error: Result cannot be sliced with []"
>
> So, kinda fixed it (correct way?):
>
> name = "this.is.a.string";
> auto nameparts = splitter(name, '.').array;
> auto name1 = joiner(nameparts[0 .. $-1], '.');
>
> got this:
>
> Error: template std.algorithm.joiner does not match any function template declaration. Candidates are:
> /usr/include/dmd/phobos/std/algorithm.d(2846): std.algorithm.joiner(RoR, Separator)(RoR r, Separator sep) if (isInputRange!RoR && isInputRange!(ElementType!RoR) && isForwardRange!Separator && is(ElementType!Separator : ElementType!(ElementType!RoR)))
>
> Stuck here, thank you for any help.
From your error message: isForwardRange!Separator
Your separator is a character, which isn't a forward range. Try this:
`auto name1 = joiner(nameparts[0 .. $-1], ".");`
|
December 31, 2013 Re: Task to throw away string parts, use joiner and splitter not very successful | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris Cain | As Chris wrote, using double quotes to use strings instead of char solves the typing issse.
I'd also suggest the following alternative, if you're going to discard a lot of last elements in your code:
import std.stdio;
import std.algorithm;
import std.array;
import std.range;
/// Return seq without its last element.
auto poppedBack (T) (T seq) if (isInputRange!T) {
seq.popBack; // Discards the last element.
return seq;
}
void main () {
// Prints "this.is.a".
"this.is.a.string"
.splitter (".")
.poppedBack
.joiner (".")
.array
.writeln;
}
On 12/31/2013 09:57 PM, Chris Cain wrote:
> On Tuesday, 31 December 2013 at 20:49:55 UTC, Dfr wrote:
>> Hello, i have string like "this.is.a.string" and want to throw away
>> some parts separated by dots, here is first attempt:
>>
>> name = "this.is.a.string"; // <-- want to make "this.is.a" from this
>> auto nameparts = splitter(name, '.');
>> auto name1 = joiner(nameparts[0 .. $-1], '.');
>>
>> And got this error: "Error: Result cannot be sliced with []"
>>
>> So, kinda fixed it (correct way?):
>>
>> name = "this.is.a.string";
>> auto nameparts = splitter(name, '.').array;
>> auto name1 = joiner(nameparts[0 .. $-1], '.');
>>
>> got this:
>>
>> Error: template std.algorithm.joiner does not match any function
>> template declaration. Candidates are:
>> /usr/include/dmd/phobos/std/algorithm.d(2846):
>> std.algorithm.joiner(RoR, Separator)(RoR r, Separator sep) if
>> (isInputRange!RoR && isInputRange!(ElementType!RoR) &&
>> isForwardRange!Separator && is(ElementType!Separator :
>> ElementType!(ElementType!RoR)))
>>
>> Stuck here, thank you for any help.
>
> From your error message: isForwardRange!Separator
>
> Your separator is a character, which isn't a forward range. Try this:
> `auto name1 = joiner(nameparts[0 .. $-1], ".");`
|
January 01, 2014 Re: Task to throw away string parts, use joiner and splitter not very successful | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris Cain | Chris Cain:
> From your error message: isForwardRange!Separator
>
> Your separator is a character, which isn't a forward range. Try this:
> `auto name1 = joiner(nameparts[0 .. $-1], ".");`
But splitting on a char is a common operation, and isn't it more efficient than splitting on a string?
Bye,
bearophile
|
January 01, 2014 Re: Task to throw away string parts, use joiner and splitter not very successful | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rémy Mouëza | This is interesting, why i can't just do it simpler way ?
"this.is.a.string"
.splitter (".")
.popBack
.joiner (".")
.array
.writeln;
Because creating an extra function is not desired.
> As Chris wrote, using double quotes to use strings instead of char solves the typing issse.
>
> I'd also suggest the following alternative, if you're going to discard a lot of last elements in your code:
> import std.stdio;
> import std.algorithm;
> import std.array;
> import std.range;
>
> /// Return seq without its last element.
> auto poppedBack (T) (T seq) if (isInputRange!T) {
> seq.popBack; // Discards the last element.
> return seq;
> }
>
> void main () {
> // Prints "this.is.a".
> "this.is.a.string"
> .splitter (".")
> .poppedBack
> .joiner (".")
> .array
> .writeln;
> }
>
>
> On 12/31/2013 09:57 PM, Chris Cain wrote:
>> On Tuesday, 31 December 2013 at 20:49:55 UTC, Dfr wrote:
>>> Hello, i have string like "this.is.a.string" and want to throw away
>>> some parts separated by dots, here is first attempt:
>>>
>>> name = "this.is.a.string"; // <-- want to make "this.is.a" from this
>>> auto nameparts = splitter(name, '.');
>>> auto name1 = joiner(nameparts[0 .. $-1], '.');
>>>
>>> And got this error: "Error: Result cannot be sliced with []"
>>>
>>> So, kinda fixed it (correct way?):
>>>
>>> name = "this.is.a.string";
>>> auto nameparts = splitter(name, '.').array;
>>> auto name1 = joiner(nameparts[0 .. $-1], '.');
>>>
>>> got this:
>>>
>>> Error: template std.algorithm.joiner does not match any function
>>> template declaration. Candidates are:
>>> /usr/include/dmd/phobos/std/algorithm.d(2846):
>>> std.algorithm.joiner(RoR, Separator)(RoR r, Separator sep) if
>>> (isInputRange!RoR && isInputRange!(ElementType!RoR) &&
>>> isForwardRange!Separator && is(ElementType!Separator :
>>> ElementType!(ElementType!RoR)))
>>>
>>> Stuck here, thank you for any help.
>>
>> From your error message: isForwardRange!Separator
>>
>> Your separator is a character, which isn't a forward range. Try this:
>> `auto name1 = joiner(nameparts[0 .. $-1], ".");`
|
January 01, 2014 Re: Task to throw away string parts, use joiner and splitter not very successful | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dfr | And one more problem here: string name = "test"; auto nameparts = splitter(name, '.'); writeln(typeof(joiner(nameparts, ".").array).stringof); This prints "dchar[]", but i need char[] or string, how to get my 'string' back ? On Tuesday, 31 December 2013 at 20:49:55 UTC, Dfr wrote: > Hello, i have string like "this.is.a.string" and want to throw away some parts separated by dots, here is first attempt: > > name = "this.is.a.string"; // <-- want to make "this.is.a" from this > auto nameparts = splitter(name, '.'); > auto name1 = joiner(nameparts[0 .. $-1], '.'); > > And got this error: "Error: Result cannot be sliced with []" > > So, kinda fixed it (correct way?): > > name = "this.is.a.string"; > auto nameparts = splitter(name, '.').array; > auto name1 = joiner(nameparts[0 .. $-1], '.'); > > got this: > > Error: template std.algorithm.joiner does not match any function template declaration. Candidates are: > /usr/include/dmd/phobos/std/algorithm.d(2846): std.algorithm.joiner(RoR, Separator)(RoR r, Separator sep) if (isInputRange!RoR && isInputRange!(ElementType!RoR) && isForwardRange!Separator && is(ElementType!Separator : ElementType!(ElementType!RoR))) > > Stuck here, thank you for any help. |
January 01, 2014 Re: Task to throw away string parts, use joiner and splitter not very successful | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dfr | The popBack function returns the element you are removing from the array, not the array itself, thus "breaking" the chaining of function.
On 01/01/2014 08:36 AM, Dfr wrote:
> This is interesting, why i can't just do it simpler way ?
>
> "this.is.a.string"
> .splitter (".")
> .popBack
> .joiner (".")
> .array
> .writeln;
>
>
> Because creating an extra function is not desired.
>
>> As Chris wrote, using double quotes to use strings instead of char
>> solves the typing issse.
>>
>> I'd also suggest the following alternative, if you're going to discard
>> a lot of last elements in your code:
>> import std.stdio;
>> import std.algorithm;
>> import std.array;
>> import std.range;
>>
>> /// Return seq without its last element.
>> auto poppedBack (T) (T seq) if (isInputRange!T) {
>> seq.popBack; // Discards the last element.
>> return seq;
>> }
>>
>> void main () {
>> // Prints "this.is.a".
>> "this.is.a.string"
>> .splitter (".")
>> .poppedBack
>> .joiner (".")
>> .array
>> .writeln;
>> }
>>
>>
>> On 12/31/2013 09:57 PM, Chris Cain wrote:
>>> On Tuesday, 31 December 2013 at 20:49:55 UTC, Dfr wrote:
>>>> Hello, i have string like "this.is.a.string" and want to throw away
>>>> some parts separated by dots, here is first attempt:
>>>>
>>>> name = "this.is.a.string"; // <-- want to make "this.is.a" from this
>>>> auto nameparts = splitter(name, '.');
>>>> auto name1 = joiner(nameparts[0 .. $-1], '.');
>>>>
>>>> And got this error: "Error: Result cannot be sliced with []"
>>>>
>>>> So, kinda fixed it (correct way?):
>>>>
>>>> name = "this.is.a.string";
>>>> auto nameparts = splitter(name, '.').array;
>>>> auto name1 = joiner(nameparts[0 .. $-1], '.');
>>>>
>>>> got this:
>>>>
>>>> Error: template std.algorithm.joiner does not match any function
>>>> template declaration. Candidates are:
>>>> /usr/include/dmd/phobos/std/algorithm.d(2846):
>>>> std.algorithm.joiner(RoR, Separator)(RoR r, Separator sep) if
>>>> (isInputRange!RoR && isInputRange!(ElementType!RoR) &&
>>>> isForwardRange!Separator && is(ElementType!Separator :
>>>> ElementType!(ElementType!RoR)))
>>>>
>>>> Stuck here, thank you for any help.
>>>
>>> From your error message: isForwardRange!Separator
>>>
>>> Your separator is a character, which isn't a forward range. Try this:
>>> `auto name1 = joiner(nameparts[0 .. $-1], ".");`
|
January 01, 2014 Re: Task to throw away string parts, use joiner and splitter not very successful | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dfr | You can use `std.conv.to` to convert the dchar[] back to a string, adding `.to!string` at the end of the dchar[] array you want to convert.
Also not that there exists two similar functions to the lazy evaluated splitter() and joiner() in std.array: the eagerly evaluated split() and join(); being eager make the code looks more straightforward (no `.array` or `.to!string`).
import std.stdio;
import std.array;
import std.algorithm;
void eager () {
string name = "thiš.ìs.à.çtriñg";
auto parts = name.split (".");
parts.popBack;
auto cut = parts.join (".");
cut.writeln;
}
void lazy_ () {
string name = "thiš.ìs.à.çtriñg";
auto parts = name.splitter (".");
parts.popBack;
auto cut = parts.joiner (".").array.to!string;
cut.writeln;
}
void main () {
eager ();
lazy_ ();
}
The program prints:
thiš.ìs.à
thiš.ìs.à
On 01/01/2014 08:40 AM, Dfr wrote:
> And one more problem here:
>
> string name = "test";
> auto nameparts = splitter(name, '.');
> writeln(typeof(joiner(nameparts, ".").array).stringof);
>
> This prints "dchar[]", but i need char[] or string, how to get my
> 'string' back ?
>
>
> On Tuesday, 31 December 2013 at 20:49:55 UTC, Dfr wrote:
>> Hello, i have string like "this.is.a.string" and want to throw away
>> some parts separated by dots, here is first attempt:
>>
>> name = "this.is.a.string"; // <-- want to make "this.is.a" from this
>> auto nameparts = splitter(name, '.');
>> auto name1 = joiner(nameparts[0 .. $-1], '.');
>>
>> And got this error: "Error: Result cannot be sliced with []"
>>
>> So, kinda fixed it (correct way?):
>>
>> name = "this.is.a.string";
>> auto nameparts = splitter(name, '.').array;
>> auto name1 = joiner(nameparts[0 .. $-1], '.');
>>
>> got this:
>>
>> Error: template std.algorithm.joiner does not match any function
>> template declaration. Candidates are:
>> /usr/include/dmd/phobos/std/algorithm.d(2846):
>> std.algorithm.joiner(RoR, Separator)(RoR r, Separator sep) if
>> (isInputRange!RoR && isInputRange!(ElementType!RoR) &&
>> isForwardRange!Separator && is(ElementType!Separator :
>> ElementType!(ElementType!RoR)))
>>
>> Stuck here, thank you for any help.
>
|
January 01, 2014 Re: Task to throw away string parts, use joiner and splitter not very successful | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rémy Mouëza | Thank you, very clear explained.
On Wednesday, 1 January 2014 at 16:31:43 UTC, Rémy Mouëza wrote:
> You can use `std.conv.to` to convert the dchar[] back to a string, adding `.to!string` at the end of the dchar[] array you want to convert.
>
> Also not that there exists two similar functions to the lazy evaluated splitter() and joiner() in std.array: the eagerly evaluated split() and join(); being eager make the code looks more straightforward (no `.array` or `.to!string`).
>
> import std.stdio;
> import std.array;
> import std.algorithm;
>
> void eager () {
> string name = "thiš.ìs.à.çtriñg";
> auto parts = name.split (".");
> parts.popBack;
> auto cut = parts.join (".");
> cut.writeln;
> }
>
> void lazy_ () {
> string name = "thiš.ìs.à.çtriñg";
> auto parts = name.splitter (".");
> parts.popBack;
> auto cut = parts.joiner (".").array.to!string;
> cut.writeln;
> }
>
> void main () {
> eager ();
> lazy_ ();
> }
>
> The program prints:
> thiš.ìs.à
> thiš.ìs.à
>
> On 01/01/2014 08:40 AM, Dfr wrote:
>> And one more problem here:
>>
>> string name = "test";
>> auto nameparts = splitter(name, '.');
>> writeln(typeof(joiner(nameparts, ".").array).stringof);
>>
>> This prints "dchar[]", but i need char[] or string, how to get my
>> 'string' back ?
>>
>>
>> On Tuesday, 31 December 2013 at 20:49:55 UTC, Dfr wrote:
>>> Hello, i have string like "this.is.a.string" and want to throw away
>>> some parts separated by dots, here is first attempt:
>>>
>>> name = "this.is.a.string"; // <-- want to make "this.is.a" from this
>>> auto nameparts = splitter(name, '.');
>>> auto name1 = joiner(nameparts[0 .. $-1], '.');
>>>
>>> And got this error: "Error: Result cannot be sliced with []"
>>>
>>> So, kinda fixed it (correct way?):
>>>
>>> name = "this.is.a.string";
>>> auto nameparts = splitter(name, '.').array;
>>> auto name1 = joiner(nameparts[0 .. $-1], '.');
>>>
>>> got this:
>>>
>>> Error: template std.algorithm.joiner does not match any function
>>> template declaration. Candidates are:
>>> /usr/include/dmd/phobos/std/algorithm.d(2846):
>>> std.algorithm.joiner(RoR, Separator)(RoR r, Separator sep) if
>>> (isInputRange!RoR && isInputRange!(ElementType!RoR) &&
>>> isForwardRange!Separator && is(ElementType!Separator :
>>> ElementType!(ElementType!RoR)))
>>>
>>> Stuck here, thank you for any help.
|
January 02, 2014 Re: Task to throw away string parts, use joiner and splitter not very successful | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Wednesday, 1 January 2014 at 00:19:39 UTC, bearophile wrote:
> Chris Cain:
>
>> From your error message: isForwardRange!Separator
>>
>> Your separator is a character, which isn't a forward range. Try this:
>> `auto name1 = joiner(nameparts[0 .. $-1], ".");`
>
> But splitting on a char is a common operation, and isn't it more efficient than splitting on a string?
>
> Bye,
> bearophile
The "separator" here is actually a joiner element. "splitter(range, '.')" *does* work.
AFAIK, there should be no problem providing a "joiner(RoR, E)". I think it's on my "todo".
I think the "issue" was that the overload *may* have been ambiguous...? I'll have to double check.
|
Copyright © 1999-2021 by the D Language Foundation