0
$\begingroup$

This question is strongly related to:

Map and Apply a function on a nested list

I am in a bit of a rut in terms of my MMA skills and looking to improve my coding. I've realized that rather than taking advantage of all of capabilities of MMA, I've stuck to a few constructs that are easy coming from a procedural background such as using Table to replicate While-Do functionality.

I often have to deal with nested lists:

 n1 = 3; n2 = 6; n3 = 5; (*example*)

 list1 = Table[Table[RandomInteger[{-5, 5}, n1], {i, 1, n2, 1}], {j, 1, n3, 1}];
 list2 = Table[Table[RandomInteger[{-5, 5}, n1], {i, 1, n2, 1}], {j, 1, n3, 1}];
 list3 = Table[Table[RandomInteger[{-5, 5}, n1], {i, 1, n2, 1}], {j, 1, n3, 1}];
 list = {list1, list2, list3};     

I typically have to apply some set of functions to the nested list as follows:

values1 = Table[Min@list1[[i]][[All, #]] & /@ Range[n1], {i, 1, n3}];
values2 = Table[Max@list2[[i]][[All, #]] & /@ Range[n1], {i, 1, n3}];
values3 = Table[StandardDeviation@list3[[i]][[All, #]] & /@ Range[n1], {i, 1, n3}];
values = {values1, values2, values3};

And plot the results:

Grid[{{ListLinePlot[Transpose@values1, PlotStyle -> {Red}, PlotMarkers -> "x"]
, ListLinePlot[Transpose@values2, PlotStyle -> {Green}, PlotMarkers -> "y"]
, ListLinePlot[Transpose@values3, PlotStyle -> {Blue}, PlotMarkers -> "z"]}}]

Question: How would you rewrite ALL of the above code (including the list generation and plotting) in a functional style (without using Table) so that it is efficient and expandable?

$\endgroup$
  • $\begingroup$ @Mr.Wizard: Made one more edit on value generation.... $\endgroup$ – Pam May 11 '14 at 17:31
  • $\begingroup$ Thanks for the Accept. However, I just noticed that in your update you used a different function (StandardDeviation) for values3; is that important? $\endgroup$ – Mr.Wizard May 11 '14 at 18:44
  • $\begingroup$ MrW: thanks for that… yes, I need to apply Min/Max and StDev to list1 thru 3... $\endgroup$ – Pam May 11 '14 at 22:58
  • $\begingroup$ Okay, I'll address that. $\endgroup$ – Mr.Wizard May 11 '14 at 22:59
4
$\begingroup$

List generation can be done with this:

list = RandomInteger[{-5, 5}, {3, 5, 6, 3}];

The values list can be calculated without inputting specific dimensions; only depth is needed. I write a Function to handle one expression, then Map it onto list at levelspec {2}:

values = Map[Min /@ Transpose[#] &, list, {2}];

Edit: Or following your updated question, with a separate function for each sublist:

values =
  MapThread[
    Map[#2, Transpose /@ #, {2}] &,
    {list, {Min, Max, StandardDeviation}}
  ];

Plotting can be done by writing one function, then passing it arguments using MapThread:

MapThread[
  ListLinePlot[Transpose @ #, PlotStyle -> #2, PlotMarkers -> #3] &,
  {values, {Red, Green, Blue}, {"x", "y", "z"}}
] // List // Grid

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.