www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - array to string functional?

reply berni <someone somemail.de> writes:
a) I've got an int[] which contains only 0 und 1. And I want to 
end with a string, containing 0 and 1. So [1,1,0,1,0,1] should 
become "110101". Of course I can do this with a loop and ~. But I 
think it should be doable with functional style, which is 
something I would like to understand better. Can anyone help me 
here? (I think a.map!(a=>to!char(a+'0')) does the trick, but is 
this good style or is there a better way?)

b) After having this I'd like to split this resulting string into 
chunks of a fixed length, e.g. length 4, so "110101" from above 
should become ["1101","01"]. Again, is it possible to do that 
with functional style? Probably chunks from std.range might help 
here, but I don't get it to work.

All in all, can you fill in the magic functional chain below?

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

 auto result = magic functional chain here :-)

 assert(result==["1011","1010","1111","0"]);
Sep 14 2018
parent reply SrMordred <patric.dexheimer gmail.com> writes:
On Friday, 14 September 2018 at 19:44:37 UTC, berni wrote:
 a) I've got an int[] which contains only 0 und 1. And I want to 
 end with a string, containing 0 and 1. So [1,1,0,1,0,1] should 
 become "110101". Of course I can do this with a loop and ~. But 
 I think it should be doable with functional style, which is 
 something I would like to understand better. Can anyone help me 
 here? (I think a.map!(a=>to!char(a+'0')) does the trick, but is 
 this good style or is there a better way?)

 b) After having this I'd like to split this resulting string 
 into chunks of a fixed length, e.g. length 4, so "110101" from 
 above should become ["1101","01"]. Again, is it possible to do 
 that with functional style? Probably chunks from std.range 
 might help here, but I don't get it to work.

 All in all, can you fill in the magic functional chain below?

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

 auto result = magic functional chain here :-)

 assert(result==["1011","1010","1111","0"]);
What you want is std.range.chunks auto a = [1,0,1,1,1,0,1,0,1,1,1,1,0]; a.map!(to!string) .join("") .chunks(4) .map!(to!string) //don´t know why the chunks are not already strings at this point ;/ .writeln;
Sep 14 2018
next sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Friday, 14 September 2018 at 20:43:45 UTC, SrMordred wrote:
 What you want is std.range.chunks


 auto a = [1,0,1,1,1,0,1,0,1,1,1,1,0];
     a.map!(to!string)
      .join("")
      .chunks(4)
      .map!(to!string) //don´t know why the chunks are not 
 already strings at this point ;/
      .writeln;
It's easier if you chunk before joining: auto a = [1,0,1,1,1,0,1,0,1,1,1,1,0]; a.map!(to!string) .chunks(4) .map!join .writeln;
Sep 14 2018
parent reply berni <someone somemail.de> writes:
On Saturday, 15 September 2018 at 03:25:38 UTC, Paul Backus wrote:
 On Friday, 14 September 2018 at 20:43:45 UTC, SrMordred wrote:
 What you want is std.range.chunks


 auto a = [1,0,1,1,1,0,1,0,1,1,1,1,0];
     a.map!(to!string)
      .join("")
      .chunks(4)
      .map!(to!string) //don´t know why the chunks are not 
 already strings at this point ;/
      .writeln;
It's easier if you chunk before joining: auto a = [1,0,1,1,1,0,1,0,1,1,1,1,0]; a.map!(to!string) .chunks(4) .map!join .writeln;
Oh, thanks. What I didn't know about was join. Now I wonder how I could have found out about it, without asking here? Even yet I know it's name I cannot find it, nighter in the language documentation nor in the library documentation.
Sep 14 2018
next sibling parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Friday, September 14, 2018 11:39:48 PM MDT berni via Digitalmars-d-learn 
wrote:
 On Saturday, 15 September 2018 at 03:25:38 UTC, Paul Backus wrote:
 On Friday, 14 September 2018 at 20:43:45 UTC, SrMordred wrote:
 What you want is std.range.chunks


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

     a.map!(to!string)

      .join("")
      .chunks(4)
      .map!(to!string) //don´t know why the chunks are not

 already strings at this point ;/

      .writeln;
It's easier if you chunk before joining: auto a = [1,0,1,1,1,0,1,0,1,1,1,1,0]; a.map!(to!string) .chunks(4) .map!join .writeln;
Oh, thanks. What I didn't know about was join. Now I wonder how I could have found out about it, without asking here? Even yet I know it's name I cannot find it, nighter in the language documentation nor in the library documentation.
https://dlang.org/phobos/std_array.html#join - Jonathan M Davis
Sep 14 2018
prev sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Saturday, 15 September 2018 at 05:39:48 UTC, berni wrote:
 Oh, thanks. What I didn't know about was join. Now I wonder how 
 I could have found out about it, without asking here? Even yet 
 I know it's name I cannot find it, nighter in the language 
 documentation nor in the library documentation.
Probably the easiest way to find something in the documentation is to use the unofficial mirror at http://dpldocs.info/. Type "join" into the search box there, and you'll get `std.array.join` (the function I used) as the first result.
Sep 15 2018
parent reply berni <someone somemail.de> writes:
Anotherone I'm not getting to work: From some output with 

select part of the other lines with a regex. (I know the regex 
r".*" is quite useless, but it will be replaced by something more 
usefull.)

I tried the following, but non worked:

 output.split("\n").filter!(a=>a.length>0 && 

 output.split("\n").filter!(a=>a.length>0 && 

 output.split("\n").filter!(a=>a.length>0 && 

 output.split("\n").filter!(a=>a.length>0 && 

Any ideas?
Sep 15 2018
parent reply Paul Backus <snarwin gmail.com> writes:
On Saturday, 15 September 2018 at 20:04:36 UTC, berni wrote:
 Anotherone I'm not getting to work: From some output with 

 select part of the other lines with a regex. (I know the regex 
 r".*" is quite useless, but it will be replaced by something 
 more usefull.)

 I tried the following, but non worked:

 output.split("\n").filter!(a=>a.length>0 && 

 output.split("\n").filter!(a=>a.length>0 && 

 output.split("\n").filter!(a=>a.length>0 && 

 output.split("\n").filter!(a=>a.length>0 && 

Any ideas?
Your last example works for me: https://run.dlang.io/is/F5n3mk Can you post a complete, runnable example that illustrates your problem?
Sep 15 2018
parent berni <someone somemail.de> writes:
 Can you post a complete, runnable example that illustrates your 
 problem?
Strange as it is, now it works here too... - I don't know, what went wrong yesterday. Thanks anyway. :-)
Sep 15 2018
prev sibling next sibling parent reply bauss <jj_1337 live.dk> writes:
On Friday, 14 September 2018 at 20:43:45 UTC, SrMordred wrote:
 What you want is std.range.chunks


 auto a = [1,0,1,1,1,0,1,0,1,1,1,1,0];
     a.map!(to!string)
      .join("")
      .chunks(4)
      .map!(to!string) //don´t know why the chunks are not 
 already strings at this point ;/
      .writeln;
They're not strings, because they're now 4 ranges of integers. Then you map each of those 4 integer ranges into 4 strings.
Sep 14 2018
parent bauss <jj_1337 live.dk> writes:
On Saturday, 15 September 2018 at 06:16:59 UTC, bauss wrote:
 On Friday, 14 September 2018 at 20:43:45 UTC, SrMordred wrote:
 What you want is std.range.chunks


 auto a = [1,0,1,1,1,0,1,0,1,1,1,1,0];
     a.map!(to!string)
      .join("")
      .chunks(4)
      .map!(to!string) //don´t know why the chunks are not 
 already strings at this point ;/
      .writeln;
They're not strings, because they're now 4 ranges of integers. Then you map each of those 4 integer ranges into 4 strings.
Oh wait I didn't see your first map!(to!string) I take back what I just said.
Sep 14 2018
prev sibling parent Vladimir Panteleev <thecybershadow.lists gmail.com> writes:
On Friday, 14 September 2018 at 20:43:45 UTC, SrMordred wrote:
 On Friday, 14 September 2018 at 19:44:37 UTC, berni wrote:
 a) I've got an int[] which contains only 0 und 1. And I want 
 to end with a string, containing 0 and 1. So [1,1,0,1,0,1] 
 should become "110101". Of course I can do this with a loop 
 and ~. But I think it should be doable with functional style, 
 which is something I would like to understand better. Can 
 anyone help me here? (I think a.map!(a=>to!char(a+'0')) does 
 the trick, but is this good style or is there a better way?)
Yes, that's fine. That gives you a range; if you want an array, call array() with that expression. Also, since you know the addition won't overflow, you can substitute the to!char call with a cast (arr.map!(c => cast(char)(c + '0')).array). Another option is to index a string literal: arr.map!(c => "01"[c]).array
 auto a = [1,0,1,1,1,0,1,0,1,1,1,1,0];
     a.map!(to!string)
      .join("")
      .chunks(4)
      .map!(to!string) //don´t know why the chunks are not 
 already strings at this point ;/
      .writeln;
That's needlessly complicated and inefficient; this will allocate one string per array element. If you don't need the result to be actual arrays, this works: auto res = [1,0,1,1,1,0,1,0,1,1,1,1,0] .map!(c => "01"[c]) .chunks(4); assert(equal!equal(res, ["1011","1010","1111","0"])); If you need a real array of arrays: auto arr = res .map!array .array; assert(arr == ["1011","1010","1111","0"]);
Sep 15 2018