# Reversing every second "row" in a list

I have a list that is obtained by flattening a matrix

list=Flatten[Table[{i, j}, {i, 1, 4}, {j, 2, 6, 2}], 1]


{{1, 2}, {1, 4}, {1, 6}, {2, 2}, {2, 4}, {2, 6}, {3, 2}, {3, 4}, {3, 6}, {4, 2}, {4, 4}, {4, 6}}

And I am looking for at way to reverse all "rows" with even numbers (the first element).

So that my list will look like this

{{1,2}, {1,4}, {1,6}, {2,6}, {2,4}, {2,2}, {3,2}, {3,4}, {3,6}, {4,6}, {4, 4}, {4, 2}}


Note that the first element stays the same, but the last element (for list with even first element) for the whole "row" has reversed.

Maybe there is an easy solutions to this, but I have not been able to find it yet.

Try this

list = {{1, 2}, {1, 4}, {1, 6}, {2, 2}, {2, 4}, {2, 6}, {3, 2}, {3, 4},
{3, 6}, {4, 2}, {4, 4}, {4, 6}};
Join @@ MapAt[Reverse, #, Position[#, {{x_?EvenQ, _}, ___}]] &@ GatherBy[list, First]


{{1, 2}, {1, 4}, {1, 6}, {2, 6}, {2, 4}, {2, 2}, {3, 2}, {3, 4}, {3, 6}, {4, 6}, {4, 4}, {4, 2}}

It will be simpler if you store your list as

list2 = {{2, 4, 6}, {2, 4, 6}, {2, 4, 6}, {2, 4, 6}}


where positions is the number of "row"

MapAt[Reverse, list2, 2 ;; ;; 2]


{{2, 4, 6}, {6, 4, 2}, {2, 4, 6}, {6, 4, 2}}

• e.g. with Partition[list[[All, 2]], 3] ... Commented Nov 27, 2013 at 19:00
• Thanks. It works just fine :) The reason why the list is stored that way, is because i extracted it from a image (to one's and zeros), and used Position to extract coordinates for every one's. Thank you very much for the help. Now it's possible to make my robot draw both ways, and then minimizing the airtraveling time Commented Nov 27, 2013 at 19:14

One other solution (less tricky IMO):

list = Flatten[Table[{i, j}, {i, 1, 4}, {j, 2, 6, 2}], 1];
splittedlist = SplitBy[list, EvenQ]


{{{1, 2}, {1, 4}, {1, 6}}, {{2, 2}, {2, 4}, {2, 6}}, {{3, 2}, {3,4}, {3, 6}}, {{4, 2}, {4, 4}, {4, 6}}}

Flatten[Join[splittedlist[[#1]],Reverse@splittedlist[[#2]]] & @@@
Partition[Range@Length@splittedlist, 2],1]


{{1, 2}, {1, 4}, {1, 6}, {2, 6}, {2, 4}, {2, 2}, {3, 2}, {3, 4}, {3, 6}, {4, 6}, {4, 4}, {4, 2}}

a= {{1, 2}, {1, 4}, {1, 6}, {2, 2}, {2, 4}, {2, 6}, {3, 2}, {3, 4}, {3, 6}, {4, 2},
{4, 4}, {4, 6}}


A minor variation of ybeltukov's approach:

Flatten[If[EvenQ[#[[1, 1]]], Reverse[#], #] & /@ GatherBy[a, First],1]


Or this:

Join@@(GatherBy[a, First] /. {{x_?EvenQ, _}, z___} :> Append[Reverse[{z}], x])

Quiet[Flatten[MapIndexed[{#1, #2} &, GatherBy[list, First], {1}] /. {a_List, b_List} /;
EvenQ[b /. List -> Sequence] -> {a // Reverse, b} //. {a_List,b_List} -> a, 1]]


{{1, 2}, {1, 4}, {1, 6}, {2, 6}, {2, 4}, {2, 2}, {3, 2}, {3, 4}, {3, 6}, {4, 6}, {4, 4}, {4, 2}}

Perhaps:

fun[u_?(EvenQ[#[[1, 1]]] &)] := Reverse@u;
fun[u_] := u;
g[u_] := Flatten[fun /@ GatherBy[u, First@# &], 1];


or

fun[u_?(EvenQ[#[[1, 1]]] &)] := Reverse@u;
fun[u_] := u;
h[u_] := Join@@(fun /@ GatherBy[u, First@# &]);


Applying to test list:

list = {{1, 2}, {1, 4}, {1, 6}, {2, 2}, {2, 4}, {2, 6}, {3, 2}, {3,
4}, {3, 6}, {4, 2}, {4, 4}, {4, 6}}
g[list]


yields:

{{1, 2}, {1, 4}, {1, 6}, {2, 6}, {2, 4}, {2, 2}, {3, 2}, {3, 4}, {3,
6}, {4, 6}, {4, 4}, {4, 2}}

## SortBy

You can use SortBy with nested criteria making the second level sorting increasing or decreasing depending on whether the first element is odd:

• SortBy[list, {$f_1$, $f_2$, ...}] breaks ties by successively using the values obtained from the $f_i$.

So, we just need SortBy:

SortBy[list, {First, If[EvenQ[First@#], -#, #] &}]


{{1, 2}, {1, 4}, {1, 6}, {2, 6}, {2, 4}, {2, 2}, {3, 2}, {3, 4}, {3, 6}, {4, 6}, {4, 4}, {4, 2}}

## Partition

You can use the (undocumented) 6th argument of Partition to process the groups differently based on the parity of the first elements:

Partition[list, 3, 3, None, {},
If[OddQ @ #[[1]], Sequence @@ {##}, Sequence @@ Reverse@{##}] &]


{{1, 2}, {1, 4}, {1, 6}, {2, 6}, {2, 4}, {2, 2}, {3, 2}, {3, 4}, {3, 6}, {4, 6}, {4, 4}, {4, 2}}

Using SequenceReplace:

list={{1, 2}, {1, 4}, {1, 6}, {2, 2}, {2, 4}, {2, 6}, {3, 2}, {3, 4}, {3,
6}, {4, 2}, {4, 4}, {4, 6}};

SequenceReplace[list,
k : {{a_, _} ..} /; EvenQ[a] :> Sequence @@ Reverse[k]]


{{1, 2}, {1, 4}, {1, 6}, {2, 6}, {2, 4}, {2, 2}, {3, 2}, {3, 4}, {3,
6}, {4, 6}, {4, 4}, {4, 2}}