| Thread overview | |||||||
|---|---|---|---|---|---|---|---|
|
January 15, 2012 Fixed matrix rows joining | ||||
|---|---|---|---|---|
| ||||
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
| ||||
January 15, 2012 Re: Fixed matrix rows joining | ||||
|---|---|---|---|---|
| ||||
Posted in reply to bearophile | 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]);
}
| |||
January 15, 2012 Re: Fixed matrix rows joining | ||||
|---|---|---|---|---|
| ||||
I guess join() could be specialized for static arrays and then just do a dup and a cast? Would that work ok? | ||||
January 15, 2012 Re: Fixed matrix rows joining | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | 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.
| |||
January 15, 2012 Re: Fixed matrix rows joining | ||||
|---|---|---|---|---|
| ||||
Posted in reply to bearophile | 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 | |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply