# Looking for a better way use multiple pure functions to condense repetitive code

I have a very large 3 dimensional dataset (named pcapdata) that I have broken down for data analysis. There are 7 smaller datasets contained in the main set.

My problem is that the data is arranged in a strange way, where there are 3 different sensors I must account for, and the rows of data alternate between the 3 sensors. After breaking down pcapdata into the 7 smaller datasets, I used pure functions to take the data of each sensor using the Take, and I repeated that 3 times for each sensor

papoints =
Take[pcapdata[[#]], {1, Length[pcapdata[[#]]], 3}] & /@ {1, 2, 3, 4, 5, 6, 7};
pbpoints =
Drop[Take[pcapdata[[#]], {2, Length[pcapdata[[#]]], 3}], -2] & /@
{1, 2, 3, 4, 5, 6, 7};
pcpoints =
Take[pcapdata[[#]], {3, Length[pcapdata[[#]]], 3}] & /@ {1, 2, 3, 4, 5, 6, 7};


These three lines grab every third row of data, starting from row 1, 2, and 3, respectively. Aside from the Drop function, these lines are about the same, aside from the (1, 2, 3). I was wondering if there were some way to use two pure functions (or something else) to reduce this down to one line. I have seen a few examples using #1 and #2 on this forum as well as mathematica's website. However, I couldn't get this to work on my own since my #1 and #2 were lists.

Any help would be greatly appreciated. If the 3 resulting datasets from these 3 lines were condensed into one variable, it would dramatically reduce the amount of code in other regions of my project.

You can use a single pure function:

ClearAll[f]
f = #[[All, #2 ;; -#2 If[#2 == 2, 3, 1] ;; 3]] &;

{papoints, pbpoints, pcpoints} = f[pcapdata, #]& /@ Range


Alternatively,

ClearAll[f2]
f2[d_, k_] := d[[All, k ;; -k If[k == 2, 3, 1] ;; 3]]
{papoints, pbpoints, pcpoints} = f2[pcapdata, #]& /@ Range


Can you try this?
I believe you'll get the same results..

T[x_] :=Take[s=pcapdata[[#]],{x,Length@s,3}]&/@Range@7
papoints = T
pbpoints = {#}&@@@T
pcpoints = T


This answer is not as sophisticated nor as concise as kglr's, but I think it may be easier to understand.

First, for testing purposes, I contrive some data which I believe has the same structure as yours.

SeedRandom; pcapdata = RandomReal[1, {7, 12, 3}];


Next I repeat your calculations with the test data to get validation set.

papoints =
Take[pcapdata[[#]], {1, Length[pcapdata[[#]]], 3}] & /@ {1, 2, 3, 4,5, 6, 7};
pbpoints =
Drop[Take[pcapdata[[#]], {2, Length[pcapdata[[#]]], 3}], -2] & /@ {1, 2, 3, 4, 5, 6, 7};
pcpoints =
Take[pcapdata[[#]], {3, Length[pcapdata[[#]]], 3}] & /@ {1, 2, 3, 4, 5, 6, 7};


Now I do a single computation that computes the first and last result needed and an intermediate result for the second result.

{papts, tmp, pcpts} =
Table[
f /@ Range,
{f, Function[k, Take[pcapdata[[#]], {k, -1, 3}] &] /@ Range}];


Finally, I compute the second needed result.

pbpts = Drop[#, -2] & /@ tmp;


### Validation

And @@ {papoints == papts, pbpoints == pbpts, pcpoints == pcpts}


True