digitalmars.D.learn - Fixed matrix rows joining
- bearophile (36/36) Jan 14 2012 If I have a simple fixed-size matrix and I need to linearize (flatten) i...
- Andrej Mitrovic (13/13) Jan 14 2012 A rectangular array is really just one array, is it not? From a syntax
- Andrej Mitrovic (2/2) Jan 14 2012 I guess join() could be specialized for static arrays and then just do
- Peter Alexander (2/4) Jan 15 2012 There should be no need to allocate extra memory to do this.
- Timon Gehr (5/41) Jan 15 2012 join(map!((int[] a)=>a)(table[]))
If I have a simple fixed-size matrix and I need to linearize (flatten) it, the function join() seems to not not work: import std.array: join; void main() { int[4][4] table; join(table); } test.d(4): Error: template std.array.join(RoR,R) if (isInputRange!(RoR) && isInputRange!(ElementType!(RoR)) && isForwardRange!(R) && is(Unqual!(ElementType!(ElementType!(RoR))) == Unqual!(ElementType!(R)))) does not match any function template declaration test.d(4): Error: template std.array.join(RoR,R) if (isInputRange!(RoR) && isInputRange!(ElementType!(RoR)) && isForwardRange!(R) && is(Unqual!(ElementType!(ElementType!(RoR))) == Unqual!(ElementType!(R)))) cannot deduce template function from argument types !()(int[4u][4u]) This too doesn't work: join(table[]); This compiles: join(map!q{ a[] }(table[])); But this program shows there is something wrong (I know what's wrong), it prints: [6, 4219787, 4, 6, 4219787, 4] import std.stdio: writeln; import std.algorithm: map; import std.array: join; void main() { int[3][2] table = [[1,2,3],[4,5,6]]; int[] result = join(map!q{ a[] }(table[])); writeln(result); } This prints the right output, but it allocates lot of memory: [1, 2, 3, 4, 5, 6] import std.stdio: writeln; import std.algorithm: map; import std.array: join; void main() { int[3][2] table = [[1,2,3],[4,5,6]]; int[] result2 = join(map!q{ a.dup }(table[])); writeln(result2); } Do you have better suggestions? Is the function join() worth fixing/changing to improve this use case? Bye, bearophile
Jan 14 2012
A rectangular array is really just one array, is it not? From a syntax point it looks like a multidimensional array but really it's just a single linear piece of memory, so just cast it: void main() { int[2][4] table; table[0][] = 0; table[1][] = 1; table[2][] = 2; table[3][] = 3; auto x = cast(int[])table; assert(x == [0, 0, 1, 1, 2, 2, 3, 3]); }
Jan 14 2012
I guess join() could be specialized for static arrays and then just do a dup and a cast? Would that work ok?
Jan 14 2012
On 15/01/12 2:19 AM, Andrej Mitrovic wrote:I guess join() could be specialized for static arrays and then just do a dup and a cast? Would that work ok?There should be no need to allocate extra memory to do this.
Jan 15 2012
On 01/15/2012 02:38 AM, bearophile wrote:If I have a simple fixed-size matrix and I need to linearize (flatten) it, the function join() seems to not not work: import std.array: join; void main() { int[4][4] table; join(table); } test.d(4): Error: template std.array.join(RoR,R) if (isInputRange!(RoR)&& isInputRange!(ElementType!(RoR))&& isForwardRange!(R)&& is(Unqual!(ElementType!(ElementType!(RoR))) == Unqual!(ElementType!(R)))) does not match any function template declaration test.d(4): Error: template std.array.join(RoR,R) if (isInputRange!(RoR)&& isInputRange!(ElementType!(RoR))&& isForwardRange!(R)&& is(Unqual!(ElementType!(ElementType!(RoR))) == Unqual!(ElementType!(R)))) cannot deduce template function from argument types !()(int[4u][4u]) This too doesn't work: join(table[]); This compiles: join(map!q{ a[] }(table[])); But this program shows there is something wrong (I know what's wrong), it prints: [6, 4219787, 4, 6, 4219787, 4] import std.stdio: writeln; import std.algorithm: map; import std.array: join; void main() { int[3][2] table = [[1,2,3],[4,5,6]]; int[] result = join(map!q{ a[] }(table[])); writeln(result); } This prints the right output, but it allocates lot of memory: [1, 2, 3, 4, 5, 6] import std.stdio: writeln; import std.algorithm: map; import std.array: join; void main() { int[3][2] table = [[1,2,3],[4,5,6]]; int[] result2 = join(map!q{ a.dup }(table[])); writeln(result2); } Do you have better suggestions?join(map!((int[] a)=>a)(table[])) although I'd like join(map!((ref a)=>a[])(table[])) to work. I'll file an enhancement.Is the function join() worth fixing/changing to improve this use case? Bye, bearophile
Jan 15 2012