7
$\begingroup$

Suppose I have the following list:

Tl={{a, 3, b}, {c, 6, d}, {e, 9, f}, {g, 5, h}}

I really want to reverse specific elements of this list such that I get the following:

lT= {{b,5, a}, {d, 9, c}, {f, 6, e}, {h, 3, g}}

The best I could do is:

Reverse /@ tl

(* output: {{b, 3, a}, {d, 6, c}, {f, 9, e}, {h, 5, g}} *)

Any suggestions? The method should hold for any even number (say N) of sublists (consisting of 3 elements) in the original data set. As can be seen, N=4 for this case.

$\endgroup$
  • $\begingroup$ lt=tl;lt[[All,2]]=Reverse@lt[[All,2]] $\endgroup$ – ciao Oct 5 '15 at 6:04
  • 2
    $\begingroup$ @ciao I also think the first and third elements are reversed $\endgroup$ – Peter Roberge Oct 5 '15 at 6:20
  • $\begingroup$ @PeterRoberge: Yep, missed that... $\endgroup$ – ciao Oct 5 '15 at 6:51
4
$\begingroup$

I'll solve this in two parts to better see what's going on.

(changing variable to t)

t = {{a, 3, b}, {c, 6, d}, {e, 9, f}, {g, 5, h}}

Part one will create sub-lists of the first and third element of each list:

p1 = Map[Reverse, t[[All, {1, 3}]]]

{{b, a}, {d, c}, {f, e}, {h, g}}

Part two will reverse the second element:

p2 = Reverse [t[[All, 2]]]

{5, 9, 6, 3}

Then put it all back together:

Transpose[{p1[[All, 1]], p2[[All]], p1[[All, 2]]}]

{{b, 5, a}, {d, 9, c}, {f, 6, e}, {h, 3, g}}
$\endgroup$
7
$\begingroup$
Transpose[{#[[;; , 3]], #[[-1 ;; 1 ;; -1, 2]], #[[;; , 1]]}] &@lt

or

Transpose[{#3, Reverse[#2], #1}] & @@ Transpose[lt]
$\endgroup$
  • 1
    $\begingroup$ Nice use of apply, +1 $\endgroup$ – LLlAMnYP Oct 5 '15 at 6:36
  • $\begingroup$ This is a beauty! $\endgroup$ – thils Oct 5 '15 at 6:37
  • $\begingroup$ @LLlAMnYP thanks, but I still feel like we are missing a shorter solution :) $\endgroup$ – Kuba Oct 5 '15 at 6:37
  • 2
    $\begingroup$ Thread[{#3,Reverse@#2,#1}&@@Transpose@m] is 5 characters shorter than yours. I don't see a shorter solution... (and that's mostly thanks to syntactic sugar) $\endgroup$ – LLlAMnYP Oct 5 '15 at 6:46
  • 1
    $\begingroup$ @LLlAMnYP Keep in mind you can use :tr: syntax too :) $\endgroup$ – Kuba Oct 5 '15 at 7:11
6
$\begingroup$

Here's a one-liner:

m = {{a, 3, b}, {c, 6, d}, {e, 9, f}, {g, 5, h}}

Reverse /@ Transpose@MapAt[Reverse, Transpose[m], 2]

(* {{b, 5, a}, {d, 9, c}, {f, 6, e}, {h, 3, g}} *)

Here's another one:

MapThread[Riffle, {m[[All, {3, 1}]], m[[-1 ;; 1 ;; -1, {2}]]}]

And another:

Thread[{m[[All, 3]], m[[-1 ;; 1 ;; -1, 2]], m[[All, 1]]}]

Also, as suggested by @Kuba, which is shorter yet in the notebook. Unfortunately, the font in the editor doesn't support the superscripted "T" for transposition (it's unicode F3C7), so it doesn't look as nice here. is equivalent to :tr:.

{#3, Reverse@#2, #1} & @@ (m)

The challenge remains to make this even shorter.

$\endgroup$
  • $\begingroup$ Both are good answers! $\endgroup$ – thils Oct 5 '15 at 6:35

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.