5
$\begingroup$

Suppose we have the following data list

data = {{-1, 2}, {0, 3}, {6, 6}, {1}, {-5, 1}, {0, 0}, {3}, {-3, 3}, {1, 2}, {1}, 
        {0, -1}, {2, 2}, {7}, {5, 5}, {2, 2}, {3, -3}, {4, -4}, {2, -2}, {7}}

The data are formatted as follows: first, we have N rows of (a,b) elements and then a row with a single element c which determines the end and the class of the (a,b) sub-list. My question: how can I choose all the (a,b) elements for a given value of c?

For example, in the above list choose all elements for which c = 1 and create data2 as

data2 = {{-1, 2}, {0, 3}, {6, 6}, {-3, 3}, {1, 2}}
$\endgroup$
1
  • 2
    $\begingroup$ Split[data, ! MatchQ[#1, {_}] &] // Cases[#, {x___, {1}} :> x] & ? $\endgroup$
    – andre314
    Apr 3, 2021 at 8:46

2 Answers 2

6
$\begingroup$

This answer is inspired from the answer given by kglr in your other question:

data = {{-1, 2}, {0, 3}, {6, 6}, {1}, {-5, 1}, {0, 0}, {3}, {-3, 
    3}, {1, 2}, {1}, {0, -1}, {2, 2}, {7}, {5, 5}, {2, 
    2}, {3, -3}, {4, -4}, {2, -2}, {7}};

First split them:

SequenceCases[data, {a : {_, _} .., {b_}} :> b -> Sequence[a]]

(*Out: {1 -> Sequence[{-1, 2}, {0, 3}, {6, 6}], 
 3 -> Sequence[{-5, 1}, {0, 0}],
 1 -> Sequence[{-3, 3}, {1, 2}], 
 7 -> Sequence[{0, -1}, {2, 2}], 
 7 -> Sequence[{5, 5}, {2, 2}, {3, -3}, {4, -4}, {2, -2}]}*)

Then apply Merge to merge duplicate keys:

result = Merge[
  SequenceCases[data, {a : {_, _} .., {b_}} :> b -> Sequence[a]], 
  Identity]

(*Out: <|1 -> {{-1, 2}, {0, 3}, {6, 6}, {-3, 3}, {1, 2}}, 
 3 -> {{-5, 1}, {0, 0}}, 
 7 -> {{0, -1}, {2, 2}, {5, 5}, {2, 2}, {3, -3}, {4, -4}, {2, -2}}|>*)

Just give your value c as key to the result:

result[1]

(*Out: {{-1, 2}, {0, 3}, {6, 6}, {-3, 3}, {1, 2}} *)

result[7]

(*Out: {{0, -1}, {2, 2}, {5, 5}, {2, 2}, {3, -3}, {4, -4}, {2, -2}} *)
$\endgroup$
6
$\begingroup$
split = Split[data, Length @ # != 1 &];

Column @ split

enter image description here

You can use GroupBy to get an Association with singleton elements in data used as keys:

grouped = GroupBy[split, First @* Last -> Most]
<|1 -> {{{-1, 2}, {0, 3}, {6, 6}}, {{-3, 3}, {1, 2}}}, 
  3 -> {{{-5, 1}, {0, 0}}}, 
  7 -> {{{0, -1}, {2, 2}}, {{5, 5}, {2, 2}, {3, -3}, {4, -4}, {2, -2}}}|>

You can Query grouped:

grouped @ 1
 {{{-1, 2}, {0, 3}, {6, 6}}, {{-3, 3}, {1, 2}}}

and extract desired Parts:

First @ grouped @1
{{-1, 2}, {0, 3}, {6, 6}}

or use Part directly:

grouped[[1, 1]]
{{-1, 2}, {0, 3}, {6, 6}}
$\endgroup$
1
  • 3
    $\begingroup$ Or GroupBy[split, First@*Last -> Most, Apply[Join]] $\endgroup$
    – eldo
    Aug 21, 2023 at 9:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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