Search
Is there a more elegant way to do this in D?
Apr 08
Apr 08
Jack
Apr 08
Jack
Apr 09
ddcovery
Apr 08
Meta
Apr 08
Meta

I am trying to take an array and convert it to a string. I know that Split will let me easily go the other way. I searched for the converse of Split but have not been able to locate it. I can think of two brute force methods of doing this. I found an answer to something similar in the forum and adapted it - but it is so much code for such a simple procedure:

``````import std;
void main()
{
auto a = [1,0,1,1,1,0,1,0,1,1,1,1,0];

string b = to!string(a.map!(to!string)
.chunks(a.length)
.map!join);

string f = b[2..b.length-2];  //needed to strip the first two and las two characters
writeln(f);

}
``````

I want to come out of this with a string that looks like this: 1011101011110

```On 4/7/21 8:57 PM, Brad wrote:

>      auto a = [1,0,1,1,1,0,1,0,1,1,1,1,0];

> I want to come out of this with a string that looks like this: 1011101011110

Me, me, me, me! :)

import std;
void main()
{
auto a = [1,0,1,1,1,0,1,0,1,1,1,1,0];

string s = format!"%-(%s%)"(a);
writeln(s);
}

Ali

```

On Thursday, 8 April 2021 at 03:57:23 UTC, Brad wrote:

>

I am trying to take an array and convert it to a string. I know that Split will let me easily go the other way. I searched for the converse of Split but have not been able to locate it.

You need two functions here:

1. `joiner` [1], which lazily joins the elements of a range.
2. `array` [2], which eagerly evaluates a range and returns an array of its elements.

The final code looks like this:

``````dchar[] b = a.map!(to!string).joiner.array;
``````

You may have noticed that the type of `b` here is `dchar[]`, not `string`. This is due to a feature of D's standard library known as "auto decoding" [3]. To prevent the strings you get from `to!string` from being auto-decoded into ranges of `dchar`, you can use the function `std.utf.byCodeUnit` [4], like this:

``````string b = a.map!(to!string).map!(byCodeUnit).joiner.array;
``````

On Thursday, 8 April 2021 at 03:57:23 UTC, Brad wrote:

>

I am trying to take an array and convert it to a string. I know that Split will let me easily go the other way. I searched for the converse of Split but have not been able to locate it. I can think of two brute force methods of doing this. I found an answer to something similar in the forum and adapted it - but it is so much code for such a simple procedure:

``````import std;
void main()
{
auto a = [1,0,1,1,1,0,1,0,1,1,1,1,0];

string b = to!string(a.map!(to!string)
.chunks(a.length)
.map!join);

string f = b[2..b.length-2];  //needed to strip the first two and las two characters
writeln(f);

}
``````

I want to come out of this with a string that looks like this: 1011101011110

``````string to01String(int[] x) @safe
{
auto conv = x.to!(ubyte[]); // allocates new array, so later cast to string is OK
conv[] += '0'; // assume all numbers are 0-9, then this gives the correct result
return (() @trusted => cast(string)conv)();
}
``````
```On Thursday, 8 April 2021 at 04:02:26 UTC, Ali Çehreli wrote:
> On 4/7/21 8:57 PM, Brad wrote:
>
>>      auto a = [1,0,1,1,1,0,1,0,1,1,1,1,0];
>
>> I want to come out of this with a string that looks like this: 1011101011110
>
> Me, me, me, me! :)
>
> import std;
> void main()
> {
>   auto a = [1,0,1,1,1,0,1,0,1,1,1,1,0];
>
>   string s = format!"%-(%s%)"(a);
>   writeln(s);
> }
>
> Ali

What does %-%s% do?
```
```On Thursday, 8 April 2021 at 16:45:14 UTC, Jack wrote:
> On Thursday, 8 April 2021 at 04:02:26 UTC, Ali Çehreli wrote:
>> On 4/7/21 8:57 PM, Brad wrote:
>>
>>>      auto a = [1,0,1,1,1,0,1,0,1,1,1,1,0];
>>
>>> I want to come out of this with a string that looks like this: 1011101011110
>>
>> Me, me, me, me! :)
>>
>> import std;
>> void main()
>> {
>>   auto a = [1,0,1,1,1,0,1,0,1,1,1,1,0];
>>
>>   string s = format!"%-(%s%)"(a);
>>   writeln(s);
>> }
>>
>> Ali
>
> What does %-%s% do?

nevermind, someone just asked this too[1]

```

On Thursday, 8 April 2021 at 12:19:29 UTC, WebFreak001 wrote:

>
``````string to01String(int[] x) @safe
{
auto conv = x.to!(ubyte[]); // allocates new array, so later cast to string is OK
conv[] += '0'; // assume all numbers are 0-9, then this gives the correct result
return (() @trusted => cast(string)conv)();
}
``````

The @trusted lambda can also be replaced with std.exception.assumeUnique.

On Thursday, 8 April 2021 at 18:01:56 UTC, Meta wrote:

>

On Thursday, 8 April 2021 at 12:19:29 UTC, WebFreak001 wrote:

>
``````string to01String(int[] x) @safe
{
auto conv = x.to!(ubyte[]); // allocates new array, so later cast to string is OK
conv[] += '0'; // assume all numbers are 0-9, then this gives the correct result
return (() @trusted => cast(string)conv)();
}
``````

The @trusted lambda can also be replaced with std.exception.assumeUnique.

Never mind me, assumeUnique is @system (or at least it's inferred as @system), and anyway, you can't implicitly convert `immutable(ubyte)[]` to `immutable(char)[]`.

The ascii code of 0 is 48 so I think you can add everywhere 48 (but I'm not a specialist)

```On Thu, Apr 08, 2021 at 08:28:44PM +0000, Alain De Vos via Digitalmars-d-learn wrote:
> The ascii code of 0 is 48 so I think you can add everywhere 48 (but
> I'm not a specialist)

Why bother with remembering it's 48? Just add '0', like this:

int a = [1, 0, 1, 0, 1, ...];
string s = a.map!(i => cast(char)(i + '0')).array;
writeln(s);

Or better yet, if you just want to output it and don't need to store the array, just use the range directly:

int a = [1, 0, 1, 0, 1, ...];
auto r = a.map!(i => cast(char)(i + '0'));
writeln(r);

T

--
People say I'm arrogant, and I'm proud of it.
```
« First   ‹ Prev
1 2