www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Best syntax for a diagonal and vertical slice

reply kerdemdemir <kerdemdemir hotmail.com> writes:
We have awesome way for creating slices like:

     a = new int[5];
     int[] b = a[0..2];

But what about if I have 2D array and I don't want to go 
vertical. Something like :

int[3][3] matrix = [
     [ 1, 2, 3 ],
     [ 4, 5, 6 ],
     [ 7, 8, 9 ]
];

I believe I can use std.range function "RoundRobin"(or maybe it 
won't work with 2D array directly) for having a good looking 
vertical slice which will have 1,4,7 or 2,5,8 or 3,6,9 in my 
example above.

And what if I want to go diagonal like 1,5,9 or 3,5,7 in the 
example above. Is there a good solution in std without using for 
loops?

I have one more requirement for fulfilling the task that I 
working on. This slices do not have to be the same size as the 
array. For example in the example above slice size could have 2 
instead of 3. In this case I need to have slices like 
1,5;2,6;4,8;5,9 ... and so on for diagonal case.

Erdem

Ps: Converting the 2D array to 1D array is possible in my case.
Jul 22
next sibling parent pineapple <meapineapple gmail.com> writes:
On Saturday, 22 July 2017 at 20:55:06 UTC, kerdemdemir wrote:
 And what if I want to go diagonal like 1,5,9 or 3,5,7 in the 
 example above. Is there a good solution in std without using 
 for loops?
I suggest using an actual matrix type for tasks like this. I don't know about diagonal slicing, but the implementation here at least provides accessors for both rows and columns. https://github.com/pineapplemachine/mach.d/blob/master/mach/math/matrix.d
Jul 24
prev sibling next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 22.07.2017 22:55, kerdemdemir wrote:
 We have awesome way for creating slices like:
 
      a = new int[5];
      int[] b = a[0..2];
 
 But what about if I have 2D array and I don't want to go vertical. 
 Something like :
 
 int[3][3] matrix = [
      [ 1, 2, 3 ],
      [ 4, 5, 6 ],
      [ 7, 8, 9 ]
 ];
 
 I believe I can use std.range function "RoundRobin"(or maybe it won't 
 work with 2D array directly) for having a good looking vertical slice 
 which will have 1,4,7 or 2,5,8 or 3,6,9 in my example above.
 
 And what if I want to go diagonal like 1,5,9 or 3,5,7 in the example 
 above. Is there a good solution in std without using for loops?
 
 I have one more requirement for fulfilling the task that I working on. 
 This slices do not have to be the same size as the array. For example in 
 the example above slice size could have 2 instead of 3. In this case I 
 need to have slices like 1,5;2,6;4,8;5,9 ... and so on for diagonal case.
 
 Erdem
 
 Ps: Converting the 2D array to 1D array is possible in my case.
horizontal: matrix[i][j..j+k] vertical: matrix[i..i+k].map!(x=>x[j]) diagonal 1: iota(k).map!(x=>matrix[i+x][j+x]) diagonal 2: iota(k).map!(x=>matrix[i+x][j-x])
Jul 24
prev sibling parent Ilya Yaroshenko <ilyayaroshenko gmail.com> writes:
On Saturday, 22 July 2017 at 20:55:06 UTC, kerdemdemir wrote:
 We have awesome way for creating slices like:

     a = new int[5];
     int[] b = a[0..2];

 But what about if I have 2D array and I don't want to go 
 vertical. Something like :

 int[3][3] matrix = [
     [ 1, 2, 3 ],
     [ 4, 5, 6 ],
     [ 7, 8, 9 ]
 ];

 I believe I can use std.range function "RoundRobin"(or maybe it 
 won't work with 2D array directly) for having a good looking 
 vertical slice which will have 1,4,7 or 2,5,8 or 3,6,9 in my 
 example above.

 And what if I want to go diagonal like 1,5,9 or 3,5,7 in the 
 example above. Is there a good solution in std without using 
 for loops?

 I have one more requirement for fulfilling the task that I 
 working on. This slices do not have to be the same size as the 
 array. For example in the example above slice size could have 2 
 instead of 3. In this case I need to have slices like 
 1,5;2,6;4,8;5,9 ... and so on for diagonal case.

 Erdem

 Ps: Converting the 2D array to 1D array is possible in my case.
Hello Erdem, You may want to use mir-algorithm DUB package. It is a D tensor library. https://github.com/libmir/mir-algorithm import mir.ndslice; auto slice = matrix[0].ptr.sliced(3, 3); auto row = matrix[0]; auto col = matrix[0 .. $, 0]; A lot of examples with diagonal and sub-diagonals can be found here http://docs.algorithm.dlang.io/latest/mir_ndslice_topology.html#.diagonal Best, Ilya
Aug 25