May 18, 2015 Re: How to create a mutable array of strings? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dennis Ritchie | 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 Re: How to create a mutable array of strings? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | 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 strings Now 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 Re: How to create a mutable array of strings? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dennis Ritchie | On 5/18/15 9:55 AM, Dennis Ritchie wrote: > 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 strings > > Now 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; 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")]; > 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 > 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. -Steve |
May 18, 2015 Re: How to create a mutable array of strings? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | 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. |
Copyright © 1999-2021 by the D Language Foundation