digitalmars.D - initializedArray
- Andrej Mitrovic (18/18) Dec 20 2011 I think it would be cool to have an initializedArray function, which
- Paul D. Anderson (11/32) Dec 20 2011 I think this is a great idea and a good example of adding to the
- Dejan Lekic (2/2) Dec 20 2011 I would go even further, and give a *function* as an argument -
- Andrej Mitrovic (5/7) Dec 20 2011 Well I don't know about functions yet, but I did need to use another
- Andrej Mitrovic (1/1) Dec 20 2011 *Also those two templates can be merged, I just have to change the const...
- Philippe Sigaud (18/24) Dec 20 2011 from : http://www.ideone.com/gKFTK :
- Andrej Mitrovic (26/36) Dec 20 2011 dup is not a deep copy, it only copies the first elements. The first
- Philippe Sigaud (25/51) Dec 20 2011 =C2=A0?
- Andrej Mitrovic (6/13) Dec 21 2011 That returns an array, but I can't pass an array in place of a
- Andrej Mitrovic (3/16) Dec 21 2011 Ok just realized I can't use a mixin, lengths are dynamic, heheh. That
I think it would be cool to have an initializedArray function, which creates and initializes an array with a *specific* initializer. A hardcoded example would be: import std.array; auto initializedArray(F:float[])(size_t size, float init) { auto arr = uninitializedArray!(float[])(size); arr[] = init; return arr; } void main() { float[] arr = initializedArray!(float[])(3, 0.0f); assert(arr[] == [0.0f, 0.0f, 0.0f]); } Currently there's no D syntax for using new on arrays and specifying a specific initializer, so maybe we should have this as a library function. Thoughts?
Dec 20 2011
I think this is a great idea and a good example of adding to the library rather than changing the syntax. Paul "Wouldn't the sentence 'I want to put a hyphen between the words Fish and And and And and Chips in my Fish-And-Chips sign' have been clearer if quotation marks had been placed before Fish, and between Fish and and, and and and And, and And and and, and and and And, and And and and, and and and Chips, as well as after Chips?" — Martin Gardner On Tuesday, 20 December 2011 at 12:55:18 UTC, Andrej Mitrovic wrote:I think it would be cool to have an initializedArray function, which creates and initializes an array with a *specific* initializer. A hardcoded example would be: import std.array; auto initializedArray(F:float[])(size_t size, float init) { auto arr = uninitializedArray!(float[])(size); arr[] = init; return arr; } void main() { float[] arr = initializedArray!(float[])(3, 0.0f); assert(arr[] == [0.0f, 0.0f, 0.0f]); } Currently there's no D syntax for using new on arrays and specifying a specific initializer, so maybe we should have this as a library function. Thoughts?
Dec 20 2011
I would go even further, and give a *function* as an argument - function that will be used to initialise values.
Dec 20 2011
On 12/20/11, Dejan Lekic <dejan.lekic gmail.com> wrote:I would go even further, and give a *function* as an argument - function that will be used to initialise values.Well I don't know about functions yet, but I did need to use another array as an initializer. So the new implementation takes care of that via lockstep: http://www.ideone.com/gKFTK
Dec 20 2011
*Also those two templates can be merged, I just have to change the constraints.
Dec 20 2011
On Tue, Dec 20, 2011 at 21:20, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:On 12/20/11, Dejan Lekic <dejan.lekic gmail.com> wrote:from : http://www.ideone.com/gKFTK : unittest { auto arr2 = initializedArray!(int[][])([[1, 2], [3, 4]], 2, 2); assert(arr2 == [[1, 2], [3, 4]]); } 1) What's the difference with using auto arr2 == [[1,2],[3,4]].dup; ? (I honestly asks, I don't know much about D's assignements) 2) You can get the lengths of [[1,2],[3,4]], so the 2,2 args is redundant. What happens if you type: auto arr2 = initializedArray!(int[][])([[1, 2], [3, 4]], 4, 10); 3) I still think you should relax the constraint on the init value's type. You do not need it to be *exactly* BaseElementType!T. Thats stops you from writing auto arr2 = initializedArray!(float[][])(3, 2,3); 4-ish) No need to attribute the rank/BaseElementType code to me :-)I would go even further, and give a *function* as an argument - function that will be used to initialise values.Well I don't know about functions yet, but I did need to use another array as an initializer. So the new implementation takes care of that via lockstep:
Dec 20 2011
On 12/20/11, Philippe Sigaud <philippe.sigaud gmail.com> wrote:1) What's the difference with using auto arr2 == [[1,2],[3,4]].dup; ? (I honestly asks, I don't know much about D's assignements)dup is not a deep copy, it only copies the first elements. The first elements are two slices, so: void main() { auto a = [[1, 2], [3, 4]]; auto b = a.dup; a[0][0] = 10; assert(b[] == [[1, 2], [3, 4]]); // fails, b[0][0] is 10 }2) You can get the lengths of [[1,2],[3,4]], so the 2,2 args is redundant. What happens if you type: auto arr2 = initializedArray!(int[][])([[1, 2], [3, 4]], 4, 10);Right, it's broken to say the least. That's what I get for a 10 second implementation.. Btw, uninitializedArray takes variadic arguments, how would I get the lengths of the dimensions as a tuple that can be passed in place of the variadic argument? I.e.: auto dupArray(int[][] src) // say src is int[1][2] { auto arr = uninitializedArray!(int[][])( /* need 1, 2 here */ ); // ..then copy each element.. } I could use a mixin, but there should be an easier way to do this? You're good with templates so I'm asking you! :)3) I still think you should relax the constraint on the init value's type. You do not need it to be *exactly* BaseElementType!T. Thats stops you from writing auto arr2 = initializedArray!(float[][])(3, 2,3);I often fall to this trap. I think there's a syntax for checking if a type is implicitly convertible to another type? I haven't read your book fully yet, btw.4-ish) No need to attribute the rank/BaseElementType code to me :-)I say the same thing for when people use my code, but usually it's best not to assume ownership. :)
Dec 20 2011
On Tue, Dec 20, 2011 at 23:42, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:On 12/20/11, Philippe Sigaud <philippe.sigaud gmail.com> wrote:=C2=A0?1) What's the difference with using auto arr2 =3D=3D [[1,2],[3,4]].dup; =Ah OK. Where as your version does a deep dupping, I see.(I honestly asks, I don't know much about D's assignements)dup is not a deep copy, it only copies the first elements. The first elements are two slicesI tend to do that also :)2) You can get the lengths of [[1,2],[3,4]], so the 2,2 args is redundant. What happens if you type: auto arr2 =3D initializedArray!(int[][])([[1, 2], [3, 4]], 4, 10);Right, it's broken to say the least. That's what I get for a 10 second implementation..Btw, uninitializedArray takes variadic arguments, how would I get the lengths of the dimensions as a tuple that can be passed in place of the variadic argument? I.e.: auto dupArray(int[][] src) =C2=A0// say src is int[1][2] { =C2=A0 =C2=A0auto arr =3D uninitializedArray!(int[][])( /* need 1, 2 here=*/ );=C2=A0 =C2=A0// ..then copy each element.. }Having thought a bit more about this, there is a difference between static and dynamic arrays. For static arrays, the length is part of the type, so getting them should be straightforward. Untested: size_t[] arrayLengths(A)(A a) if (isStaticArray!A) { static if (isStaticArray!(ElementType!A)) return arrayLengths(a[0]) ~ a.length; else return [a.length]; } But for dynamic arrays, int[][] can be a jagged (non square) array. And now that array literal are dynamic, the only way I see would be to collect the max length for all dimensions. [[1,2,3], [4,5]] -> 2 rows, 3 columns.There is 'is(A : B)', but when I tried this with your code, it didn't work (maybe I was confused between double and floats). That's why I used std.traits.isImplicitlyConvertible!(From,To)3) I still think you should relax the constraint on the init value's type. You do not need it to be *exactly* BaseElementType!T. Thats stops you from writing auto arr2 =3D initializedArray!(float[][])(3, =C2=A02,3);I often fall to this trap. I think there's a syntax for checking if a type is implicitly convertible to another type?
Dec 20 2011
On 12/21/11, Philippe Sigaud <philippe.sigaud gmail.com> wrote:size_t[] arrayLengths(A)(A a) if (isStaticArray!A) { static if (isStaticArray!(ElementType!A)) return arrayLengths(a[0]) ~ a.length; else return [a.length]; }That returns an array, but I can't pass an array in place of a variadic argument. The prototype of uninitializedArray is: auto uninitializedArray(T, I...)(I sizes) if(allSatisfy!(isIntegral, I)) { }
Dec 21 2011
Ok just realized I can't use a mixin, lengths are dynamic, heheh. That went over my head. I'll see what else I can do.. On 12/21/11, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:On 12/21/11, Philippe Sigaud <philippe.sigaud gmail.com> wrote:size_t[] arrayLengths(A)(A a) if (isStaticArray!A) { static if (isStaticArray!(ElementType!A)) return arrayLengths(a[0]) ~ a.length; else return [a.length]; }That returns an array, but I can't pass an array in place of a variadic argument. The prototype of uninitializedArray is: auto uninitializedArray(T, I...)(I sizes) if(allSatisfy!(isIntegral, I)) { }
Dec 21 2011