digitalmars.D.learn - Return complete multi-dimensional array after appending
- eXodiquas (32/32) Sep 15 2021 Howdy everyone. :)
- Paul Backus (26/38) Sep 15 2021 You need to use `~=` instead of `~` to mutate an existing array:
- eXodiquas (9/48) Sep 15 2021 Oooh, I totally forgot you can open blocks like this in anonymous
Howdy everyone. :) Today I came across a small problem (I mean, I could solve it by writing a function that solves my problem, but maybe there is something in std that can help me here). Let's say we have the following code: ```d void main() { int[][] a = [[],[]]; (a[0] ~ 5).writeln; // => [5] } ``` it's quite obvious that `[5]` is printed. Because I am a fan of one-liners (we do small code challenges, and I want to show what's possible with fold) and ridiculous stuff I tried to do something like this: ```d [1,0,3,4,0,5] .fold!((a, e) => e != 0 ? a[0] ~ e : a[1] ~ e)(cast(int[][]) [[],[]]) .flatten .writeln ``` This should sort all non 0s into the `a[0]` array and all 0s into the `a[1]` array. But it won't work because the `~` does not return the whole array (which is probably better for most of the cases). So the question, is there a way to do this kind of append, but getting the whole array back as a result in std? And another question, is there a way to tell `fold` about the initial value of an empty list without having to cast a `void[]` into the list of the desired type? Thanks in advance. :) eXodiquas
Sep 15 2021
On Wednesday, 15 September 2021 at 20:32:12 UTC, eXodiquas wrote:```d [1,0,3,4,0,5] .fold!((a, e) => e != 0 ? a[0] ~ e : a[1] ~ e)(cast(int[][]) [[],[]]) .flatten .writeln ``` This should sort all non 0s into the `a[0]` array and all 0s into the `a[1]` array. But it won't work because the `~` does not return the whole array (which is probably better for most of the cases). So the question, is there a way to do this kind of append, but getting the whole array back as a result in std?You need to use `~=` instead of `~` to mutate an existing array: ```d import std; void main() { [1, 0, 3, 4, 0, 5] .fold!((a, e) { e != 0 ? (a[0] ~= e) : (a[1] ~= e); return a; })(cast(int[][]) [[], []]) .joiner .writeln; } ``` Of course, a more idiomatic solution would be to use `std.algorithm.partition`: ```d import std; void main() { auto arr = [1, 0, 3, 4, 0, 5]; arr.partition!(e => e != 0); // in-place arr.writeln; } ```
Sep 15 2021
On Wednesday, 15 September 2021 at 21:02:29 UTC, Paul Backus wrote:On Wednesday, 15 September 2021 at 20:32:12 UTC, eXodiquas wrote:Oooh, I totally forgot you can open blocks like this in anonymous functions. Now I look a bit stupid. Thanks. :) `partition` is also very nice. D std is so huge, I should sketch out a roadmap or something. That's why I asked the question in the first place because deep inside I knew there is a function in std that solves the problem. Thanks for the answer. :)```d [1,0,3,4,0,5] .fold!((a, e) => e != 0 ? a[0] ~ e : a[1] ~ e)(cast(int[][]) [[],[]]) .flatten .writeln ``` This should sort all non 0s into the `a[0]` array and all 0s into the `a[1]` array. But it won't work because the `~` does not return the whole array (which is probably better for most of the cases). So the question, is there a way to do this kind of append, but getting the whole array back as a result in std?You need to use `~=` instead of `~` to mutate an existing array: ```d import std; void main() { [1, 0, 3, 4, 0, 5] .fold!((a, e) { e != 0 ? (a[0] ~= e) : (a[1] ~= e); return a; })(cast(int[][]) [[], []]) .joiner .writeln; } ``` Of course, a more idiomatic solution would be to use `std.algorithm.partition`: ```d import std; void main() { auto arr = [1, 0, 3, 4, 0, 5]; arr.partition!(e => e != 0); // in-place arr.writeln; } ```
Sep 15 2021