5
$\begingroup$

I have a way to solve my problem, but it seems like there should be something better. Also I realize that I probably don't have a good enough handle on how to get at parts of lists the way I need to. I'm doing the following, which gets me the result I need:

x = {
   {{"a", "b", "c"}, 12},
   {{"q", "b", "c"}, 32},
   {{"w", "b", "c"}, 11},
   {{"a", "b", "d"}, 22}
   };

GatherBy[Partition[Flatten[x, 2], 4][[All, 2 ;;]], #[[;; 2]] &]

{{{"b", "c", 12}, {"b", "c", 32}, {"b", "c", 11}}, {{"b", "d", 22}}}

I'm gathering these list elements by the 2nd and 3rd element of the first list in each row. I want to group those numeric elements. The only way I can think of solving this is flattening the list to get rid of the "list within a list" problem. Is there a better way to handle this?

$\endgroup$
4
$\begingroup$
Map[Flatten, GatherBy[x, #[[1, 2 ;;]] &], {2}][[All, All, 2 ;;]]
$\endgroup$
  • $\begingroup$ All of the answers work well. I "accepted" this one because it shows me a little more about accessing the proper elements in my list. There are a few others that might also do that, but I'm still trying to understand them. Trying to understand all of these answers has been an education and a half! $\endgroup$ – Mitchell Kaplan Sep 29 '14 at 17:10
6
$\begingroup$

Somewhat easier to read:

GatherBy[Map[Rest @* Flatten, x], Most]

(* {{{"b", "c", 12}, {"b", "c", 32}, {"b", "c", 11}}, {{"b", "d", 22}}} *)

Pre V10 version:

GatherBy[Map[Composition[Rest, Flatten], x], Most]
$\endgroup$
  • $\begingroup$ The Bracket-free notation doesn't seem to gather like items. The others work - I don't understand them yet, but they work. I need to look up a few things before I'll understand them. $\endgroup$ – Mitchell Kaplan Sep 26 '14 at 21:23
  • $\begingroup$ @MitchelKaplan D'oh. My eyes aren't too good. Thanks. $\endgroup$ – Michael E2 Sep 26 '14 at 21:26
  • $\begingroup$ Short and for any fairly recent version: GatherBy[Rest /@ Flatten /@ x, Most] $\endgroup$ – Mr.Wizard Sep 26 '14 at 22:58
3
$\begingroup$
f = GatherBy[{##2 & @@ #1, #2} & @@@ #, Most] &;
f@x
(* {{{"b","c",12},{"b","c",32},{"b","c",11}},{{"b","d",22}}} *)

or

f2 = Gather[{##2 & @@ #1, #2} & @@@ #, Equal @@ Most /@ {##} &] &;
f2@x
(*  {{{"b","c",12},{"b","c",32},{"b","c",11}},{{"b","d",22}}} *)
$\endgroup$
2
$\begingroup$
 Gather[Cases[x, {{_, x__}, z_} :> {x, z}], #1[[;; 2]] == #2[[;; 2]] &]
(*{{{"b", "c", 12}, {"b", "c", 32}, {"b", "c", 11}}, {{"b", "d", 22}}}*)
$\endgroup$
0
$\begingroup$
sow[{{_, a_, b_}, n_}] := Sow[{a, b, n}, h[a, b]]
Reap[sow /@ x] // Last

{{{"b", "c", 12}, {"b", "c", 32}, {"b", "c", 11}}, {{"b", "d", 22}}}

$\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.