4
$\begingroup$

I have a data set that looks like this:

lis = {a,{{b,c},{d,e}},m,{p,q}}

Each single element of the list ("a" and "m" in this example) is followed by one or more sublists consisting of two elements ("{b,c}", "{d,e}" and "{p,q}" in this example). I would like to tag each sublist pair with its preceding single element, turning the list into:

lis2 = {{b,c,a},{d,e,a},{p,q,m}}

I would be interested in an efficient way of doing this, and thank you in advance for any ideas.

$\endgroup$

3 Answers 3

4
$\begingroup$

Split with a custom test is the first thing that comes to mind. And then Map to assemble the results.

lis = {a, {{b, c}, {d, e}}, m, {p, q}};
splitlis = Split[lis, Not[ListQ[#1]] && ListQ[#2] &];
mapfun[{x_, y_}] := Map[Append[#, x] &, Partition[Flatten[y], 2]];
Flatten[Map[mapfun, splitlis], 1]

(* {{b, c, a}, {d, e, a}, {p, q, m}} *)

$\endgroup$
2
  • $\begingroup$ There's nothing in the question to suggest that the initial split couldn't just be Partition[lis, 2]. $\endgroup$
    – wxffles
    Commented Nov 2, 2016 at 3:30
  • $\begingroup$ Works like a charm. Thanks! $\endgroup$
    – Suite401
    Commented Nov 2, 2016 at 5:30
1
$\begingroup$

Assuming that the lis has a recurring pattern of a Symbol followed by either a list of lists or a vector, two definitions must be employed for processing.

Clear["Global`*"]
f[{a_Symbol, b_?VectorQ}] := {Sequence @@ b, a}
f[{a_Symbol, b : {__List}}] := (Append[#, a] & /@ b ) // 
  Apply[Sequence]

SequenceReplace[lis
 , {a_Symbol, b_List} :> f[{a, b}]
 ]

{{b, c, a}, {d, e, a}, {p, q, m}}

$\endgroup$
1
$\begingroup$

1.

SequenceReplace[lis, 
  {{a_, b : {__List}} :> Splice[Append[a] /@ b], 
   {a_, b : {__}} :> Append[a] @ b}]
{{b, c, a}, {d, e, a}, {p, q, m}}

2.

If[ListQ @ First @ #2, Splice[Append[#] /@ #2], Append[#] @ #2] & @@@ 
  Split[lis, ListQ @ #2 &]
{{b, c, a}, {d, e, a}, {p, q, m}}

3.

{a___, b_, takeOver[c_], d___} ^:= 
   {a, If[ListQ @ First @ c, Splice[Append[b] /@ c], Append[b] @ c], d}

Replace[lis, x_List :> takeOver[x], {1}]
{{b, c, a}, {d, e, a}, {p, q, m}}
$\endgroup$
3
  • $\begingroup$ The first two sublists are different compared to what's stated in the OP. $\endgroup$
    – Syed
    Commented Apr 27, 2023 at 9:40
  • $\begingroup$ Thank you @Syed. I can't see a simple fix; so deleting for now. $\endgroup$
    – kglr
    Commented Apr 27, 2023 at 10:38
  • $\begingroup$ The third variation is much above my current skill level. Thanks for this comprehensive answer. $\endgroup$
    – Syed
    Commented May 2, 2023 at 3:44

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.