6
$\begingroup$

I have a long flat list that needs to be partitioned. The list is formatted so the "header" is repeated, followed by the values. Essentially, it looks something like this:

list={a,a,1,2,3,b,b,5,6,c,c,1,5,a,a,7,8,9,1}

I am looking for an output of:

{{a,1,2,3},{b,5,6},{c,1,5},{a,7,8,9,1}}

The output above would then let me create the association list I need.

Obviously Partition won't work because the sublists are of different lengths. I have looked at various ways to identify where the repeated "header" data is, but that doesn't help with the splits.

$\endgroup$
  • $\begingroup$ What is the header data? Is it symbols? Or a string? Or also numbers? $\endgroup$ – Henrik Schumacher Sep 21 '18 at 14:53
  • $\begingroup$ In the actual data, all items would be treated as strings $\endgroup$ – kickert Sep 21 '18 at 14:56
  • 1
    $\begingroup$ Should the list be split any duplicate or are there some known header strings? $\endgroup$ – Henrik Schumacher Sep 21 '18 at 14:59
  • $\begingroup$ All headers will repeat and none of the following values will repeat. There is a chance that sets will have the same headers. Essentially, anytime a value is equal to the value before it, it can be used as the split point. $\endgroup$ – kickert Sep 21 '18 at 15:10
8
$\begingroup$
Join[Most /@ Rest @ Most @ #, {Last @ #}] & @ Split[list, UnsameQ]

{{a, 1, 2, 3}, {b, 5, 6}, {c, 1, 5}, {a, 7, 8, 9, 1}}

You can also use use Split twice and reorganize the result:

Rest /@ Flatten /@ Split[Split[list], Length @ #2 == 1 &]

{{a, 1, 2, 3}, {b, 5, 6}, {c, 1, 5}, {a, 7, 8, 9, 1}}

And yet an alternative way:

Take[list, {#, #2 - 2}] & @@@ 
 Partition[Last /@ SequencePosition[list, {a_, a_}], 2, 1, 1, {Length[list] + 2}] 

{{a, 1, 2, 3}, {b, 5, 6}, {c, 1, 5}, {a, 7, 8, 9, 1}}

$\endgroup$
  • $\begingroup$ That seems to have done it. Let me dig into the final output to see if there is any trickery going on. $\endgroup$ – kickert Sep 21 '18 at 15:11
  • $\begingroup$ Okay, I think I am following. Normally Split puts all the same repeated elements together, but by specifying that UnsameQ you are grouping things that are dissimilar. That makes sense. Then by mapping Most you are dropping the last element of each sublist. I am not quite sure I understand what you are doing with the the Replace all and SlotSequence. Obviously the first list will be invalid, but couldn't you just use Rest[Most /@ Split[list, UnsameQ]] Thanks for the guidance! $\endgroup$ – kickert Sep 21 '18 at 17:25
  • 1
    $\begingroup$ @kickert, the original answer was incorrect. Fixed now. Thank you for the accept. $\endgroup$ – kglr Sep 21 '18 at 18:25
  • $\begingroup$ Right or wrong, all your solutions got me where I needed to be. $\endgroup$ – kickert Sep 21 '18 at 18:44
7
$\begingroup$
SequenceSplit[list, {a_, a_, x:_Integer ..} -> {a,x}]

{{a, 1, 2, 3}, {b, 5, 6}, {c, 1, 5}, {a, 7, 8, 9, 1}}

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