digitalmars.D.learn - How to create a mutable array of strings?
- Dennis Ritchie (6/6) May 17 2015 Hi,
- Dennis Ritchie (5/11) May 17 2015 It's uncomfortable:
- Dennis Ritchie (4/4) May 17 2015 This option is also a strange:
- Steven Schveighoffer (13/17) May 18 2015 It's annoying to have to dup each one.
- Dennis Ritchie (20/32) May 18 2015 Yes, it's really annoying. However, the problem can be solved as
- Steven Schveighoffer (17/42) May 18 2015 Right, you'd apply the map/array combo to each element:
- Dennis Ritchie (6/23) May 18 2015 Yes, I knew it.
- Jack Applegame (3/7) May 17 2015 auto s = ["foo".dup, "bar".dup];
- Daniel Kozak via Digitalmars-d-learn (4/12) May 17 2015 On Sun, 17 May 2015 09:06:38 +0000
- Daniel Kozak via Digitalmars-d-learn (7/15) May 17 2015 On Sun, 17 May 2015 09:06:38 +0000
- Dennis Ritchie (2/3) May 17 2015 Thanks. This version I was completely satisfied.
- anonymous (8/11) May 17 2015 Remember that Daniel Kozak wrote "if you are sure thats what you
- Dennis Ritchie (2/14) May 17 2015 And no crashes on Windows :)
- anonymous (9/10) May 17 2015 Yeah, on windows it's even worse.
- Dennis Ritchie (2/12) May 17 2015 Yes exactly.
- Daniel Kozak (3/6) May 17 2015 So maybe this one would be ok with you too :)
- Dennis Ritchie (2/4) May 17 2015 Now it works :)
- "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> (6/22) May 17 2015 That's not a good idea. I haven't checked, but this will likely
- Daniel Kozak (2/26) May 17 2015 Yep, you are right, shame on me :)
- Dennis Ritchie (22/22) May 17 2015 I remembered code Ali Çereli. It really helped:
- Daniel Kozak via Digitalmars-d-learn (6/35) May 17 2015 On Sun, 17 May 2015 09:39:21 +0000
- Daniel Kozak (2/38) May 17 2015 Ouch ignore this one :D
- Dennis Ritchie (2/3) May 17 2015 Yes, it will not work with multidimensional arrays :)
- Daniel Kozak (3/19) May 17 2015 But I am unsure if this will work in case where immutable data
Hi, It seems to me, or D do not create mutable array of strings? How to create a mutable equivalent of a string array? ----- string[] s = ["foo", "bar"]; // s[1][1] = 't'; // immutable expression s[1][1]
May 17 2015
On Sunday, 17 May 2015 at 09:06:40 UTC, Dennis Ritchie wrote:Hi, It seems to me, or D do not create mutable array of strings? How to create a mutable equivalent of a string array? ----- string[] s = ["foo", "bar"]; // s[1][1] = 't'; // immutable expression s[1][1]It's uncomfortable: ----- char[][] s = [['f', 'o', 'o'], ['b', 'a', 'r']]; s[1][1] = 't';
May 17 2015
This option is also a strange: char[][] s = ["foo".dup, "bar".dup]; s[1][1] = 't'; In my opinion, you need to add to D keyword mutable.
May 17 2015
On 5/17/15 5:15 AM, Dennis Ritchie wrote:This option is also a strange: char[][] s = ["foo".dup, "bar".dup]; s[1][1] = 't'; In my opinion, you need to add to D keyword mutable.It's annoying to have to dup each one. But, you do have a couple other possibilities: auto s = ["foo".dup, "bar".dup]; import std.algorithm : map; import std.array : array; auto s = map!(a => a.dup)(["foo", "bar"]).array; // this will needlessly allocate an array for the strings But really, a string is immutable. There's not a way around that. A string is the most basic level of array primitive, not even mutable arrays of non-char types have that, and it's an annoyance. From there, you have to build the data out of ROM into the heap. -Steve
May 18 2015
On Monday, 18 May 2015 at 13:14:38 UTC, Steven Schveighoffer wrote:It's annoying to have to dup each one.Yes, it's really annoying. However, the problem can be solved as follows: http://forum.dlang.org/thread/owxweucyzjwugpjwhwdu forum.dlang.org?page=2#post-cqjevoldkqdkmdbenkul:40forum.dlang.org On Monday, 18 May 2015 at 13:14:38 UTC, Steven Schveighoffer wrote:But, you do have a couple other possibilities: auto s = ["foo".dup, "bar".dup]; import std.algorithm : map; import std.array : array; auto s = map!(a => a.dup)(["foo", "bar"]).array; // this will needlessly allocate an array for the stringsNow imagine that you have a multi-dimensional array of strings. This will not work: auto s = map!(a => a.dup)([["foo", "baz"], ["bar", "test"]]).array; You have to apply to each line .dup :) auto s = [["foo".dup, "baz".dup], ["bar".dup, "test".dup]]; s[1][0][1] = 't'; On Monday, 18 May 2015 at 13:14:38 UTC, Steven Schveighoffer wrote:But really, a string is immutable. There's not a way around that. A string is the most basic level of array primitive, not even mutable arrays of non-char types have that, and it's an annoyance. From there, you have to build the data out of ROM into the heap.Thank you. I do not know. And yet, the problem is easily solved. You just have to add .deepDup Phobos: http://forum.dlang.org/thread/owxweucyzjwugpjwhwdu forum.dlang.org?page=2#post-cqjevoldkqdkmdbenkul:40forum.dlang.org
May 18 2015
On 5/18/15 9:55 AM, Dennis Ritchie wrote:On Monday, 18 May 2015 at 13:14:38 UTC, Steven Schveighoffer wrote:Right, you'd apply the map/array combo to each element: alias m = map!(a => a.dup); // too bad can't do array as well auto s = [m(["foo", "baz"]).array, m(["bar", "test"]).array]; Or to get even more crazy: auto s = map!(a => map!(a => a.dup)(a).array)(/* your input array */).array; But this means you are duping more of the array literal than you really should. It's likely helpful to have somewhere in std.array a dupArray function that does map!(a => a.dup).array work in one go (and without making a temporary array): auto s = [dupArray("foo", "baz"), dupArray("bar", "test")];It's annoying to have to dup each one.Yes, it's really annoying. However, the problem can be solved as follows: http://forum.dlang.org/thread/owxweucyzjwugpjwhwdu forum.dlang.org?page=2#post-cqjevoldkqdkmdbenkul:40forum.dlang.org On Monday, 18 May 2015 at 13:14:38 UTC, Steven Schveighoffer wrote:But, you do have a couple other possibilities: auto s = ["foo".dup, "bar".dup]; import std.algorithm : map; import std.array : array; auto s = map!(a => a.dup)(["foo", "bar"]).array; // this will needlessly allocate an array for the stringsNow imagine that you have a multi-dimensional array of strings. This will not work: auto s = map!(a => a.dup)([["foo", "baz"], ["bar", "test"]]).array;On Monday, 18 May 2015 at 13:14:38 UTC, Steven Schveighoffer wrote:deepDup would dup the whole thing. All you need to dup is the string literals, as array literals constructed at runtime are on the heap (and mutable) already. The literal already is wasted even in my original suggestion, but this is doubly wasteful. -SteveBut really, a string is immutable. There's not a way around that. A string is the most basic level of array primitive, not even mutable arrays of non-char types have that, and it's an annoyance. From there, you have to build the data out of ROM into the heap.Thank you. I do not know. And yet, the problem is easily solved. You just have to add ..deepDup Phobos: http://forum.dlang.org/thread/owxweucyzjwugpjwhwdu forum.dlang.org?page=2#post-cqjevoldkqdkmdbenkul:40forum.dlang.org
May 18 2015
On Monday, 18 May 2015 at 14:43:33 UTC, Steven Schveighoffer wrote:Right, you'd apply the map/array combo to each element:Yes, I knew it.alias m = map!(a => a.dup); // too bad can't do array as well auto s = [m(["foo", "baz"]).array, m(["bar", "test"]).array]; Or to get even more crazy: auto s = map!(a => map!(a => a.dup)(a).array)(/* your input array */).array;Imagine a five-dimensional array will be :)But this means you are duping more of the array literal than you really should. It's likely helpful to have somewhere in std.array a dupArray function that does map!(a => a.dup).array work in one go (and without making a temporary array): auto s = [dupArray("foo", "baz"), dupArray("bar", "test")];Yes, it would be nice. I believe that Phobos need such function.deepDup would dup the whole thing. All you need to dup is the string literals, as array literals constructed at runtime are on the heap (and mutable) already. The literal already is wasted even in my original suggestion, but this is doubly wasteful.Right.
May 18 2015
On Sunday, 17 May 2015 at 09:10:06 UTC, Dennis Ritchie wrote:It's uncomfortable: ----- char[][] s = [['f', 'o', 'o'], ['b', 'a', 'r']]; s[1][1] = 't';auto s = ["foo".dup, "bar".dup]; s[1][1] = 't';
May 17 2015
On Sun, 17 May 2015 09:06:38 +0000 Dennis Ritchie via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:Hi, It seems to me, or D do not create mutable array of strings? How to create a mutable equivalent of a string array? ----- string[] s = ["foo", "bar"]; // s[1][1] = 't'; // immutable expression s[1][1]auto s = ["foo".dup, "bar".dup];
May 17 2015
On Sun, 17 May 2015 09:06:38 +0000 Dennis Ritchie via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:Hi, It seems to me, or D do not create mutable array of strings? How to create a mutable equivalent of a string array? ----- string[] s = ["foo", "bar"]; // s[1][1] = 't'; // immutable expression s[1][1]or you can use cast if you are sure thats what you really need: auto s = [cast(char[])"foo", cast(char[])"bar"]; or auto s = cast(char[][])["foo", "bar"];
May 17 2015
On Sunday, 17 May 2015 at 09:18:15 UTC, Daniel Kozak wrote:auto s = cast(char[][])["foo", "bar"];Thanks. This version I was completely satisfied.
May 17 2015
On Sunday, 17 May 2015 at 09:20:17 UTC, Dennis Ritchie wrote:On Sunday, 17 May 2015 at 09:18:15 UTC, Daniel Kozak wrote:Remember that Daniel Kozak wrote "if you are sure thats what you really need". I'm confident that you're not sure it's what you need. For starters, this crashes on linux: ---- auto s = cast(char[][])["foo", "bar"]; s[1][1] = 't'; ----auto s = cast(char[][])["foo", "bar"];Thanks. This version I was completely satisfied.
May 17 2015
On Sunday, 17 May 2015 at 09:24:19 UTC, anonymous wrote:On Sunday, 17 May 2015 at 09:20:17 UTC, Dennis Ritchie wrote:And no crashes on Windows :)On Sunday, 17 May 2015 at 09:18:15 UTC, Daniel Kozak wrote:Remember that Daniel Kozak wrote "if you are sure thats what you really need". I'm confident that you're not sure it's what you need. For starters, this crashes on linux: ---- auto s = cast(char[][])["foo", "bar"]; s[1][1] = 't'; ----auto s = cast(char[][])["foo", "bar"];Thanks. This version I was completely satisfied.
May 17 2015
On Sunday, 17 May 2015 at 09:26:15 UTC, Dennis Ritchie wrote:And no crashes on Windows :)Yeah, on windows it's even worse. void main() { auto s = cast(char[][])["foo", "bar"]; s[1][1] = 't'; import std.stdio; writeln("bar"); }
May 17 2015
On Sunday, 17 May 2015 at 09:36:33 UTC, anonymous wrote:On Sunday, 17 May 2015 at 09:26:15 UTC, Dennis Ritchie wrote:Yes exactly.And no crashes on Windows :)Yeah, on windows it's even worse. void main() { auto s = cast(char[][])["foo", "bar"]; s[1][1] = 't'; import std.stdio; writeln("bar"); }
May 17 2015
On Sunday, 17 May 2015 at 09:20:17 UTC, Dennis Ritchie wrote:On Sunday, 17 May 2015 at 09:18:15 UTC, Daniel Kozak wrote:So maybe this one would be ok with you too :) auto s = to!(char[][])(["foo", "bar"]);auto s = cast(char[][])["foo", "bar"];Thanks. This version I was completely satisfied.
May 17 2015
On Sunday, 17 May 2015 at 09:37:56 UTC, Daniel Kozak wrote:So maybe this one would be ok with you too :) auto s = to!(char[][])(["foo", "bar"]);Now it works :)
May 17 2015
On Sunday, 17 May 2015 at 09:18:15 UTC, Daniel Kozak wrote:On Sun, 17 May 2015 09:06:38 +0000 Dennis Ritchie via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:That's not a good idea. I haven't checked, but this will likely segfault on mutation, because the string literals are placed into read-only memory. And multiple identical strings are merged (shared), so that this would modify all occurances of that string literal, even if it shouldn't segfault.Hi, It seems to me, or D do not create mutable array of strings? How to create a mutable equivalent of a string array? ----- string[] s = ["foo", "bar"]; // s[1][1] = 't'; // immutable expression s[1][1]or you can use cast if you are sure thats what you really need: auto s = [cast(char[])"foo", cast(char[])"bar"]; or auto s = cast(char[][])["foo", "bar"];
May 17 2015
On Sunday, 17 May 2015 at 09:21:58 UTC, Marc Schütz wrote:On Sunday, 17 May 2015 at 09:18:15 UTC, Daniel Kozak wrote:Yep, you are right, shame on me :)On Sun, 17 May 2015 09:06:38 +0000 Dennis Ritchie via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:That's not a good idea. I haven't checked, but this will likely segfault on mutationHi, It seems to me, or D do not create mutable array of strings? How to create a mutable equivalent of a string array? ----- string[] s = ["foo", "bar"]; // s[1][1] = 't'; // immutable expression s[1][1]or you can use cast if you are sure thats what you really need: auto s = [cast(char[])"foo", cast(char[])"bar"]; or auto s = cast(char[][])["foo", "bar"];
May 17 2015
I remembered code Ali Çereli. It really helped: http://forum.dlang.org/thread/ulhtlyxxclihaseefrot forum.dlang.org#post-mihl6m:241che:241:40digitalmars.com ----- import std.stdio, std.traits, std.range, std.algorithm; auto deepDup(A)(A arr) if (isArray!A) { static if (isArray!(ElementType!A)) { return arr.map!(a => a.deepDup).array; } else { return arr.dup; } } void main() { auto s = ["foo", "bar"].deepDup; s[1][1] = 't'; writeln(s); } ----- http://rextester.com/QBFH12695 P.S. Need to enable deepDup in Phobos.
May 17 2015
On Sun, 17 May 2015 09:39:21 +0000 Dennis Ritchie via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:I remembered code Ali Çereli. It really helped: http://forum.dlang.org/thread/ulhtlyxxclihaseefrot forum.dlang.org#post-mihl6m:241che:241:40digitalmars.com ----- import std.stdio, std.traits, std.range, std.algorithm; auto deepDup(A)(A arr) if (isArray!A) { static if (isArray!(ElementType!A)) { return arr.map!(a => a.deepDup).array; } else { return arr.dup; } } void main() { auto s = ["foo", "bar"].deepDup; s[1][1] = 't'; writeln(s); } ----- http://rextester.com/QBFH12695 P.S. Need to enable deepDup in Phobos.allready there: auto s = ["foo", "bar"].map!"a.dup".array; :)
May 17 2015
On Sunday, 17 May 2015 at 09:57:05 UTC, Daniel Kozak wrote:On Sun, 17 May 2015 09:39:21 +0000 Dennis Ritchie via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:I remembered code Ali Çereli. It really helped: http://forum.dlang.org/thread/ulhtlyxxclihaseefrot forum.dlang.org#post-mihl6m:241che:241:40digitalmars.com ----- import std.stdio, std.traits, std.range, std.algorithm; auto deepDup(A)(A arr) if (isArray!A) { static if (isArray!(ElementType!A)) { return arr.map!(a => a.deepDup).array; } else { return arr.dup; } }Ouch ignore this one :Dvoid main() { auto s = ["foo", "bar"].deepDup; s[1][1] = 't'; writeln(s); } ----- http://rextester.com/QBFH12695 P.S. Need to enable deepDup in Phobos.allready there: auto s = ["foo", "bar"].map!"a.dup".array; :)
May 17 2015
On Sunday, 17 May 2015 at 10:05:34 UTC, Daniel Kozak wrote:Ouch ignore this one :DYes, it will not work with multidimensional arrays :)
May 17 2015
On Sunday, 17 May 2015 at 09:18:15 UTC, Daniel Kozak wrote:On Sun, 17 May 2015 09:06:38 +0000 Dennis Ritchie via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:But I am unsure if this will work in case where immutable data will occupied read only memory.Hi, It seems to me, or D do not create mutable array of strings? How to create a mutable equivalent of a string array? ----- string[] s = ["foo", "bar"]; // s[1][1] = 't'; // immutable expression s[1][1]or you can use cast if you are sure thats what you really need: auto s = [cast(char[])"foo", cast(char[])"bar"]; or auto s = cast(char[][])["foo", "bar"];
May 17 2015