www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Finding Max Value of Column in Multi-Dimesional Array

reply Samir <samir aol.com> writes:
Is there a cleaner way of finding the maximum value of say the 
third column in a multi-dimensional array than this?
int[][] p = [[1,2,3,4], [9,0,5,4], [0,6,2,1]];
writeln([p[0][2], p[1][2], p[2][2]].max);

I've tried the following
writeln([0, 1, 2].map!(p[a][2]).max);

but get an "Error: undefined identifier a" error.

I know there doesn't seem to be much of a difference between two 
examples but my real-world array is more complex which is why I'm 
looking for a more scalable option.

Thanks
Samir
Jul 04 2019
next sibling parent 9il <ilyayaroshenko gmail.com> writes:
On Friday, 5 July 2019 at 00:54:15 UTC, Samir wrote:
 Is there a cleaner way of finding the maximum value of say the 
 third column in a multi-dimensional array than this?
 int[][] p = [[1,2,3,4], [9,0,5,4], [0,6,2,1]];
 writeln([p[0][2], p[1][2], p[2][2]].max);

 I've tried the following
 writeln([0, 1, 2].map!(p[a][2]).max);

 but get an "Error: undefined identifier a" error.

 I know there doesn't seem to be much of a difference between 
 two examples but my real-world array is more complex which is 
 why I'm looking for a more scalable option.

 Thanks
 Samir
Hi Samir, You may want to take a look into mir-algorithm [1] library. It contains ndsilce package [2] to work with multidimensional data. The following example can be run online [3]: ------ /+dub.sdl: dependency "mir-algorithm" version="~>3.4.4" +/ import mir.algorithm.iteration: reduce; import mir.ndslice: fuse, map, byDim; import mir.utility: max; import std.stdio: writeln; void main() { // create 2D matrix type of Slice!(int*, 2); auto matrix = [[1,2,3,4], [9,0,5,4], [0,6,2,1]].fuse; matrix .byDim!1 // by columns .map!(c => int.min.reduce!max(c)) .writeln; // [9, 6, 5, 4] } ------ 1. https://github.com/libmir/mir-algorithm 2. http://mir-algorithm.libmir.org/mir_ndslice.html 3. https://run.dlang.io/is/OW6zvF
Jul 04 2019
prev sibling next sibling parent Jordan Wilson <wilsonjord gmail.com> writes:
On Friday, 5 July 2019 at 00:54:15 UTC, Samir wrote:
 Is there a cleaner way of finding the maximum value of say the 
 third column in a multi-dimensional array than this?
 int[][] p = [[1,2,3,4], [9,0,5,4], [0,6,2,1]];
 writeln([p[0][2], p[1][2], p[2][2]].max);

 I've tried the following
 writeln([0, 1, 2].map!(p[a][2]).max);

 but get an "Error: undefined identifier a" error.

 I know there doesn't seem to be much of a difference between 
 two examples but my real-world array is more complex which is 
 why I'm looking for a more scalable option.

 Thanks
 Samir
p.map!(a => a[2]).maxElement.writeln; // 5 p.map!"a[2]".maxElement.writeln; // 5 Or, modifying your example: writeln([0,1,2].map!(a => p[a][2]).maxElement; Thanks, Jordan
Jul 04 2019
prev sibling next sibling parent Samir <samir aol.com> writes:
On Friday, 5 July 2019 at 01:41:38 UTC, 9il wrote:
 You may want to take a look into mir-algorithm [1] library.
 It contains ndsilce package [2] to work with multidimensional 
 data.
Thanks for referring me to this library, Ilya. I will have to check this out. While it seems a bit more complicated for my particular use case, this definitely seems like something worth checking out for future use! On Friday, 5 July 2019 at 03:02:29 UTC, Jordan Wilson wrote:
 p.map!"a[2]".maxElement.writeln; // 5
Thank you, Jordan. I think this is what I was looking for. I am still struggling to wrap my head around the use of `map` but these examples really help. Samir
Jul 05 2019
prev sibling parent reply Samir <samir aol.com> writes:
On Friday, 5 July 2019 at 00:54:15 UTC, Samir wrote:
 Is there a cleaner way of finding the maximum value of say the 
 third column in a multi-dimensional array than this?
 int[][] p = [[1,2,3,4], [9,0,5,4], [0,6,2,1]];
 writeln([p[0][2], p[1][2], p[2][2]].max);

 I've tried the following
 writeln([0, 1, 2].map!(p[a][2]).max);

 but get an "Error: undefined identifier a" error.
As a follow-on to my earlier question, is there a way to pass a variable to the `map` function that specifies the column, rather than hard-coding it? I'm thinking of something like: p.map!("a[column]").maxElement.writeln; In the mean time, I am looking further into Ilya's mir-algorithm library. Thanks Samir
Jul 05 2019
parent reply ag0aep6g <anonymous example.com> writes:
On 05.07.19 20:49, Samir wrote:
 As a follow-on to my earlier question, is there a way to pass a variable 
 to the `map` function that specifies the column, rather than hard-coding 
 it?  I'm thinking of something like:
 
 p.map!("a[column]").maxElement.writeln;
You can't do that with the string style, because the string is turned into a function inside of `map`. Your `column` isn't visible there. It works when you pass an actual callable instead, e.g. a lambda: p.map!(a => a[column]).maxElement.writeln;
Jul 05 2019
next sibling parent reply dwdv <dwdv posteo.de> writes:
On 7/5/19 9:56 PM, ag0aep6g via Digitalmars-d-learn wrote:
 On 05.07.19 20:49, Samir wrote:
 As a follow-on to my earlier question, is there a way to pass a 
 variable to the `map` function that specifies the column, rather than 
 hard-coding it?  I'm thinking of something like:

 p.map!("a[column]").maxElement.writeln;
You can't do that with the string style, because the string is turned into a function inside of `map`. Your `column` isn't visible there. It works when you pass an actual callable instead, e.g. a lambda: p.map!(a => a[column]).maxElement.writeln;
Furthermore, Samir, the parameter `a` can be renamed to whatever you prefer or what fits the code at hand best, e.g. `(row => row[column])`, as opposed to the string version, where only a small set of mostly single character names is supported.
Jul 05 2019
parent Samir <samir aol.com> writes:
On Friday, 5 July 2019 at 19:56:54 UTC, ag0aep6g wrote:
 It works when you pass an actual callable instead, e.g. a 
 lambda:

 p.map!(a => a[column]).maxElement.writeln;
On Friday, 5 July 2019 at 20:22:14 UTC, dwdv wrote:
 Furthermore, Samir, the parameter `a` can be renamed to 
 whatever you prefer or what fits the code at hand best, e.g. 
 `(row => row[column])`, as opposed to the string version, where 
 only a small set of mostly single character names is supported.
Thank you very much for the explanation! As I've mentioned before, I have a lot to learn about the `map` function and the details provided here help immensely. Samir
Jul 06 2019
prev sibling parent dwdv <dwdv posteo.de> writes:
On 7/5/19 9:56 PM, ag0aep6g via Digitalmars-d-learn wrote:
 On 05.07.19 20:49, Samir wrote:
 As a follow-on to my earlier question, is there a way to pass a 
 variable to the `map` function that specifies the column, rather than 
 hard-coding it?  I'm thinking of something like:

 p.map!("a[column]").maxElement.writeln;
You can't do that with the string style, because the string is turned into a function inside of `map`. Your `column` isn't visible there. It works when you pass an actual callable instead, e.g. a lambda: p.map!(a => a[column]).maxElement.writeln;
Furthermore, Samir, the parameter `a` can be renamed to whatever you prefer or what fits the code at hand best, e.g. `(row => row[column])`, as opposed to the string version, where only a small set of mostly single character names is supported.
Jul 05 2019