Thread overview | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
June 14, 2012 Create an array with immutable elements | ||||
---|---|---|---|---|
| ||||
immutable struct Node{ string s; } Node[] f() { Node[] arr = ...? return arr; } How to fill an array, if its elements are immutable? I want to assign values calculated by some function. |
June 15, 2012 Re: Create an array with immutable elements | ||||
---|---|---|---|---|
| ||||
Posted in reply to Roman D. Boiko | On Thursday, 14 June 2012 at 23:57:36 UTC, Roman D. Boiko wrote:
> immutable struct Node{ string s; }
> Node[] f()
> {
> Node[] arr = ...?
> return arr;
> }
>
> How to fill an array, if its elements are immutable? I want to assign values calculated by some function.
I recall this in TDPL, you can append to an array as it doesn't change it's contents, only the range the array holds... So...
Node[] f()
{
immutable(Node)[] arr;
arr ~= Node("something"); //should work?
return arr;
}
|
June 15, 2012 Re: Create an array with immutable elements | ||||
---|---|---|---|---|
| ||||
Posted in reply to Roman D. Boiko | On Thursday, 14 June 2012 at 23:57:36 UTC, Roman D. Boiko wrote:
> immutable struct Node{ string s; }
> Node[] f()
> {
> Node[] arr = ...?
> return arr;
> }
>
> How to fill an array, if its elements are immutable? I want to assign values calculated by some function.
More specifically, given
auto names = ["ab", "c", "def"] ~ getMoreNames();
retrieve
[Node("ab"), Node("abc"), Node("abcdef"), ...]
where Node is an immutable struct created dynamically, possibly with usage of some accumulating variable (in this case, a string concatenating previous values).
But an answer to the first question should be enough, this example is just for clarity.
|
June 15, 2012 Re: Create an array with immutable elements | ||||
---|---|---|---|---|
| ||||
Posted in reply to Era Scarecrow | On Friday, 15 June 2012 at 00:08:33 UTC, Era Scarecrow wrote:
> On Thursday, 14 June 2012 at 23:57:36 UTC, Roman D. Boiko wrote:
>> immutable struct Node{ string s; }
>> Node[] f()
>> {
>> Node[] arr = ...?
>> return arr;
>> }
>>
>> How to fill an array, if its elements are immutable? I want to assign values calculated by some function.
>
> I recall this in TDPL, you can append to an array as it doesn't change it's contents, only the range the array holds... So...
>
>
> Node[] f()
> {
> immutable(Node)[] arr;
> arr ~= Node("something"); //should work?
> return arr;
> }
That might be inefficient for large arrays. (In my case, arrays are small.)
Would array appender work here? I guess it should.
|
June 15, 2012 Re: Create an array with immutable elements | ||||
---|---|---|---|---|
| ||||
Posted in reply to Roman D. Boiko | Roman D. Boiko: > immutable struct Node{ string s; } > Node[] f() > { > Node[] arr = ...? > return arr; > } > > How to fill an array, if its elements are immutable? I want to assign values calculated by some function. In general sometimes it's not easy to build immutable data structures. In D there are several ways to do something similar to what you ask, some alternatives (maybe there are more possibilities): ------------------------------------- immutable struct Node { string s; } string bar(in int x) pure nothrow in { assert(x >= 0 && x <= 9); } body { return "hello" ~ cast(char)(x + '0'); } Node[] foo() { Node[] arr; enum size_t N = 5; arr.reserve(N); foreach (i; 0 .. N) arr ~= Node(bar(i)); return arr; } void main() { import std.stdio; //writeln(foo()); // try this! writeln(foo()[0]); } ------------------------------------- import std.exception; struct Node { string s; } immutable(Node)[] foo() { enum size_t N = 5; auto arr = new Node[N]; foreach (i; 0 .. N) arr[i] = Node("hello" ~ cast(char)(i + '0')); return assumeUnique(arr); } void main() { import std.stdio; writeln(foo()[0]); } ------------------------------------- struct Node { string s; } immutable(Node)[] foo() pure nothrow { enum size_t N = 5; auto arr = new Node[N]; foreach (i; 0 .. N) arr[i] = Node("hello" ~ cast(char)(i + '0')); return arr; } void main() { import std.stdio; writeln(foo()[0]); } ------------------------------------- struct Node { string s; } Node[] foo() pure nothrow { enum size_t N = 5; auto arr = new Node[N]; foreach (i; 0 .. N) arr[i] = Node("hello" ~ cast(char)(i + '0')); return arr; } void main() { import std.stdio; immutable result = foo(); writeln(result[0]); } Bye, bearophile |
June 15, 2012 Re: Create an array with immutable elements | ||||
---|---|---|---|---|
| ||||
Posted in reply to Roman D. Boiko | On Friday, June 15, 2012 01:57:35 Roman D. Boiko wrote:
> immutable struct Node{ string s; }
> Node[] f()
> {
> Node[] arr = ...?
> return arr;
> }
>
> How to fill an array, if its elements are immutable? I want to assign values calculated by some function.
There are 3 options that I know of:
1. Create an empty array and append the elements to it.
2. Use Appender (which will be more efficient than #1). e.g.
auto app = appender!(immutable Node[])();
app.put(value1);
app.put(value2);
//...
auto arr = app.data;
3. Create the array as mutable and then cast it to immutable.
auto arr = new Node[](length);
arr[0] = value1;
arr[1] = value2;
//..
auto immArr = cast(immutable(Node)[])arr;
or better
auto immArr = assumeUnique(arr);
though that will make the whole array immutable rather than just the Nodes - though that can be fixed by doing
auto immArr = assumeUnique(arr)[];
since array slices are tail-const.
- Jonathan M Davis
|
June 15, 2012 Re: Create an array with immutable elements | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Friday, 15 June 2012 at 00:14:11 UTC, bearophile wrote:
> Roman D. Boiko:
>
>> immutable struct Node{ string s; }
>> Node[] f()
>> {
>> Node[] arr = ...?
>> return arr;
>> }
>>
>> How to fill an array, if its elements are immutable? I want to assign values calculated by some function.
>
> In general sometimes it's not easy to build immutable data structures.
>
> In D there are several ways to do something similar to what you ask, some alternatives (maybe there are more possibilities):
>
Only the first example works, because assignment to immutable elements of array is not allowed. But thanks for reminding me that I can reserve desired number of elements :) This makes the first example a perfect solution for me.
|
June 15, 2012 Re: Create an array with immutable elements | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Friday, 15 June 2012 at 00:18:23 UTC, Jonathan M Davis wrote:
> On Friday, June 15, 2012 01:57:35 Roman D. Boiko wrote:
>> immutable struct Node{ string s; }
>> Node[] f()
>> {
>> Node[] arr = ...?
>> return arr;
>> }
>>
>> How to fill an array, if its elements are immutable? I want to
>> assign values calculated by some function.
>
> There are 3 options that I know of:
>
> 1. Create an empty array and append the elements to it.
>
> 2. Use Appender (which will be more efficient than #1). e.g.
>
> auto app = appender!(immutable Node[])();
> app.put(value1);
> app.put(value2);
> //...
> auto arr = app.data;
>
> 3. Create the array as mutable and then cast it to immutable.
>
> auto arr = new Node[](length);
> arr[0] = value1;
> arr[1] = value2;
> //..
> auto immArr = cast(immutable(Node)[])arr;
>
> or better
>
> auto immArr = assumeUnique(arr);
>
> though that will make the whole array immutable rather than just the Nodes -
> though that can be fixed by doing
>
> auto immArr = assumeUnique(arr)[];
>
> since array slices are tail-const.
>
> - Jonathan M Davis
Please note that type of Node is immutable. So the third option is disallowed. But I got enough answers, thanks to everybody!
|
Copyright © 1999-2021 by the D Language Foundation