digitalmars.D.learn - std.array.array seems to return flatten copy of input
- Olivier Grant (52/52) Apr 04 2014 Hi,
- anonymous (2/13) Apr 04 2014 std.range.chunks
- Tobias Pankrath (2/16) Apr 04 2014 http://dlang.org/phobos/std_range.html#chunks
- anonymous (3/37) Apr 04 2014 a.splice!(2).array is the field of the Splicer struct. Rename
- Olivier Grant (11/60) Apr 04 2014 That is one responsive D community :) Thank you to all three of
- Steven Schveighoffer (9/16) Apr 04 2014 I advise to call it _array to prevent such issues.
- Olivier Grant (6/24) Apr 04 2014 Sorry Steven,
- bearophile (13/14) Apr 04 2014 If your splice is inside another module, and you tag the array
- Olivier Grant (8/23) Apr 04 2014 Yes, that definitely seems like a good start. To be honest, I not
Hi, I've started using D as a scripting language at work and for personal projects as a means to learn the language and I've bumped into a case where I would like to iterate a slice by a certain number of elements at a time such that : foreach(s; [1,2,3,4].splice!(2)) { writeln(s); } would print : [1,2] [3,4] First of all, is there such a function in D's standard library as I didn't seem to be able to find one ? I ended up implementing the following : import std.stdio; import std.range; import std.array; auto splice( size_t N, R )( R range ) if(isInputRange!R) { struct Splicer { R array; property bool empty( ) const { return 0 == array.length; } property auto front( ) const { return array[0 .. N]; } void popFront( ) { array = array[N .. $]; } } static assert(isInputRange!Splicer); assert(range.length % N == 0); Splicer res = { range }; return res; } unittest { assert(equal([1,2,3,4].splice!(2), [[1,2],[3,4]])); } void main( ) { auto a = [1,2,3,4]; writeln(a.splice!(2)); writeln(a.splice!(2).array); } which weirdly enough gives me the following output : [[1,2],[3,4]] // I expect that. [1,2,3,4] // But what is happening here ? I'm obviously doing something wrong but I can't figure out what. Thanks for the help in advance, O.
Apr 04 2014
On Friday, 4 April 2014 at 20:19:53 UTC, Olivier Grant wrote:iterate a slice by a certain number of elements at a time such that : foreach(s; [1,2,3,4].splice!(2)) { writeln(s); } would print : [1,2] [3,4] First of all, is there such a function in D's standard library as I didn't seem to be able to find one ?std.range.chunks
Apr 04 2014
On Friday, 4 April 2014 at 20:19:53 UTC, Olivier Grant wrote:Hi, I've started using D as a scripting language at work and for personal projects as a means to learn the language and I've bumped into a case where I would like to iterate a slice by a certain number of elements at a time such that : foreach(s; [1,2,3,4].splice!(2)) { writeln(s); } would print : [1,2] [3,4] First of all, is there such a function in D's standard library as I didn't seem to be able to find one ?http://dlang.org/phobos/std_range.html#chunks
Apr 04 2014
On Friday, 4 April 2014 at 20:19:53 UTC, Olivier Grant wrote:import std.stdio; import std.range; import std.array; auto splice( size_t N, R )( R range ) if(isInputRange!R) { struct Splicer { R array; property bool empty( ) const { return 0 == array.length; } property auto front( ) const { return array[0 .. N]; } void popFront( ) { array = array[N .. $]; } } static assert(isInputRange!Splicer); assert(range.length % N == 0); Splicer res = { range }; return res; } unittest { assert(equal([1,2,3,4].splice!(2), [[1,2],[3,4]])); } void main( ) { auto a = [1,2,3,4]; writeln(a.splice!(2)); writeln(a.splice!(2).array); } which weirdly enough gives me the following output : [[1,2],[3,4]] // I expect that. [1,2,3,4] // But what is happening here ?a.splice!(2).array is the field of the Splicer struct. Rename that or call std.array.array not via UFCS.
Apr 04 2014
That is one responsive D community :) Thank you to all three of you for these quick answers. I was really scratching my head on that one. This shows that UFCS can be quite dangerous. Is there any way to hide Splicer.array to the outside world? It just seems that it would be very easy to break client code by updating your implementation if you end up using a name that is already used elsewhere and accessed using UFCS. Thanks, O. On Friday, 4 April 2014 at 20:29:28 UTC, anonymous wrote:On Friday, 4 April 2014 at 20:19:53 UTC, Olivier Grant wrote:import std.stdio; import std.range; import std.array; auto splice( size_t N, R )( R range ) if(isInputRange!R) { struct Splicer { R array; property bool empty( ) const { return 0 == array.length; } property auto front( ) const { return array[0 .. N]; } void popFront( ) { array = array[N .. $]; } } static assert(isInputRange!Splicer); assert(range.length % N == 0); Splicer res = { range }; return res; } unittest { assert(equal([1,2,3,4].splice!(2), [[1,2],[3,4]])); } void main( ) { auto a = [1,2,3,4]; writeln(a.splice!(2)); writeln(a.splice!(2).array); } which weirdly enough gives me the following output : [[1,2],[3,4]] // I expect that. [1,2,3,4] // But what is happening here ?a.splice!(2).array is the field of the Splicer struct. Rename that or call std.array.array not via UFCS.
Apr 04 2014
On Fri, 04 Apr 2014 16:35:57 -0400, Olivier Grant <against.the evil.bots.com> wrote:That is one responsive D community :) Thank you to all three of you for these quick answers. I was really scratching my head on that one. This shows that UFCS can be quite dangerous. Is there any way to hide Splicer.array to the outside world? It just seems that it would be very easy to break client code by updating your implementation if you end up using a name that is already used elsewhere and accessed using UFCS.I advise to call it _array to prevent such issues. Note, you can make the field private, but that is a module-level directive. In order for it to apply, main would have to be in a separate module. In that case, the code would simply fail to compile. As a rule, members ALWAYS have precedence over UFCS functions. -Steve
Apr 04 2014
Sorry Steven, I hadn't seen your answer. Thanks for the extra information. O. On Friday, 4 April 2014 at 20:42:32 UTC, Steven Schveighoffer wrote:On Fri, 04 Apr 2014 16:35:57 -0400, Olivier Grant <against.the evil.bots.com> wrote:That is one responsive D community :) Thank you to all three of you for these quick answers. I was really scratching my head on that one. This shows that UFCS can be quite dangerous. Is there any way to hide Splicer.array to the outside world? It just seems that it would be very easy to break client code by updating your implementation if you end up using a name that is already used elsewhere and accessed using UFCS.I advise to call it _array to prevent such issues. Note, you can make the field private, but that is a module-level directive. In order for it to apply, main would have to be in a separate module. In that case, the code would simply fail to compile. As a rule, members ALWAYS have precedence over UFCS functions. -Steve
Apr 04 2014
Olivier Grant:Is there any way to hide Splicer.array to the outside world?If your splice is inside another module, and you tag the array field with private, you will receive an error: auto splice( size_t N, R )( R range ) if(isInputRange!R) { struct Splicer { private R array; This avoids your mistake, but also forbids you to use the std.array.array on a splice with UFCS. Is this acceptable for you? Bye, bearophile
Apr 04 2014
Yes, that definitely seems like a good start. To be honest, I not familiar enough yet with how you are suppose to organise your source code in D. Is there any agreed-on naming convention when it comes to member variables to avoid that kind of name clash ? Thanks, O. On Friday, 4 April 2014 at 20:44:36 UTC, bearophile wrote:Olivier Grant:Is there any way to hide Splicer.array to the outside world?If your splice is inside another module, and you tag the array field with private, you will receive an error: auto splice( size_t N, R )( R range ) if(isInputRange!R) { struct Splicer { private R array; This avoids your mistake, but also forbids you to use the std.array.array on a splice with UFCS. Is this acceptable for you? Bye, bearophile
Apr 04 2014