14
$\begingroup$

Is there a way of smarter way of joining list of the form

l1 = {a,{b,c}};
l2 = {d,{e,f}};
l3 = {g,{h,i}};

To obtain

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

The code I have is

 {Sequence @@ #1, Flatten[#2]} & @@  Transpose[{l1, l2, l3}]
$\endgroup$

12 Answers 12

10
$\begingroup$

How about this

MapThread[Join, {l1, l2, l3}] /. Join -> Sequence

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

|improve this answer|||||
$\endgroup$
9
$\begingroup$

This seems like a good way:

l1 = {a, {b, c}};
l2 = {d, {e, f}};
l3 = {g, {h, i}};

Apply[Sequence, Thread@{l1, l2, l3}, {-2}]

(* Out: {a, d, g, {b, c, e, f, h, i}} *)

It's been a few days, but I got distracted this morning from work and revisited this... My reward was seeing poetry (+1 btw), but I also killed a couple minutes running some timings on a sampling of the various answers:

ClearAll@t;
SetAttributes[t, HoldFirst];
t[e_, n_] := First@AbsoluteTiming[Do[e, {n}];]

OP:

t[
 {Sequence @@ #1, Flatten[#2]} & @@ Transpose[{l1, l2, l3}],
 10^6
 ]

(* Out: 3.849385 *)

This answer:

t[
 Apply[Sequence, Thread@{l1, l2, l3}, {-2}],
 10^6
 ]

(* Out: 2.882288 *)

Snapshot of a few other answers:

t[
 MapThread[Join, {l1, l2, l3}] /. Join -> Sequence,
 10^6
 ]

(* Out: 5.532553 *)

t[
 MapAt[Sequence @@ # &, Transpose[{l1, l2, l3}], {{1}, {2, All}}],
 10^6
 ]

(* Out: 6.293629 *)

t[
 FlattenAt[Flatten /@ Transpose[{l1, l2, l3}], 1],
 10^6
 ]

(* Out: 3.969397*)

(Performance of this operation is probably irrelevant for the OP's purposes, but I always enjoy playing on the performance side of things.)

|improve this answer|||||
$\endgroup$
  • $\begingroup$ Whats the -2 doing in this case? $\endgroup$ – Gordon Coale Sep 26 '14 at 10:30
  • $\begingroup$ @GordonCoale ref/Apply, Details and Options: "A negative level -n consists of all parts of expr with depth n." See ref/Depth for more explanation. $\endgroup$ – William Sep 26 '14 at 14:41
8
$\begingroup$

I don't know if this is "smarter". Anyway:

ClearAll@k; SetAttributes[k, Listable];
k @@ {l1, l2, l3} /. k -> Sequence
(* {a, d, g, {b, e, h, c, f, i}} *)
|improve this answer|||||
$\endgroup$
  • 1
    $\begingroup$ I think the output OP asking for is {a,d,g,{b,c,e,f,h,i}} (Why he accepted this 囧 ?) $\endgroup$ – xzczd Sep 27 '14 at 4:44
6
$\begingroup$
♯ = {## & @@ #, ## & @@@ #2} & @@ ({##}) & ;

♯[l1, l2, l3]
(* {a, d, g, {b, c, e, f, h, i}} *)

See also: ♭ = ## & @@@ (## & @@@ {## & @@@ # & /@ #} & /@ #) &

|improve this answer|||||
$\endgroup$
  • $\begingroup$ Look, Ma! No letters! +1. You could even replace m with \[FivePointedStar]. $\endgroup$ – Michael E2 Sep 26 '14 at 17:51
  • $\begingroup$ thank you @Michael; updated with something along those lines. $\endgroup$ – kglr Sep 26 '14 at 18:07
  • $\begingroup$ This is evil. I approve. $\endgroup$ – Mr.Wizard Sep 26 '14 at 21:52
  • 1
    $\begingroup$ (1137) $\endgroup$ – Mr.Wizard Sep 26 '14 at 22:02
  • 1
    $\begingroup$ Yep, I can imagine in a near future #~♯~# == 42. @Mr.Wizard remember to give attribution. $\endgroup$ – Dr. belisarius Sep 27 '14 at 5:20
5
$\begingroup$

My take:

MapAt[Sequence @@ # &, Transpose[{l1, l2, l3}], {{1}, {2, All}}]
{a, d, g, {b, c, e, f, h, i}}
|improve this answer|||||
$\endgroup$
4
$\begingroup$

This is another way:

FlattenAt[Flatten /@ Transpose[{l1, l2, l3}], 1]

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

|improve this answer|||||
$\endgroup$
4
$\begingroup$

One option:

l1 + l2 + l3 /. Plus -> Sequence

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

|improve this answer|||||
$\endgroup$
  • 1
    $\begingroup$ @Mr.Wizard Tks!.. Now I have a nice one. $\endgroup$ – Murta Sep 26 '14 at 22:04
  • $\begingroup$ Indeed you do. Probably not as general as would be best, but then again neither are several other answers, and the OP never really specified the problem. +1 $\endgroup$ – Mr.Wizard Sep 26 '14 at 22:16
  • $\begingroup$ Similar but more abusive: Re[l1, l2, l3] /. Re@x__ :> x $\endgroup$ – Mr.Wizard Sep 26 '14 at 22:19
  • $\begingroup$ This answer has the same spirit as belisarius's, so does the output: it outputs {a, d, g, {b, e, h, c, f, i}} rather than {a, d, g, {b, c, e, f, h, i}}. $\endgroup$ – xzczd Sep 27 '14 at 4:50
3
$\begingroup$

Two very intuitive ways. First the Flattinator:

#2[#1[#1 /@ #1[{##3}, {2}], {1}], 1] &[Flatten, FlattenAt, l1, l2, l3]

and here the Padding-Miss-User

PadLeft[{Flatten[#2]}, 4, RotateLeft[#1]] & @@ Transpose[{l1, l2, l3}]

(Please don't use them. Just look and shake your head)

|improve this answer|||||
$\endgroup$
  • $\begingroup$ +1 But can't help frowning while shaking my head :) $\endgroup$ – Dr. belisarius Sep 26 '14 at 15:01
2
$\begingroup$

Rule based alternatives for completeness sake:

{l1, l2, l3} //. {{a__, {b__}}, {c_, {d__}}, 
    rest : {_, {__}} ...} :> {{a, c, {b, d}}, rest} // First

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

And:

Flatten[{l1, l2, l3}, {2, 1}] /. {start__, rest : {_, _} ...} :> {start, Join[rest]}

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

|improve this answer|||||
$\endgroup$
  • 1
    $\begingroup$ Ha! I was tempted too :) $\endgroup$ – Dr. belisarius Sep 25 '14 at 23:03
2
$\begingroup$

Another solution :

Join[#[[1]], {#[[2]]}] &@(Flatten /@ Transpose@{l1, l2, l3})
(* {a, d, g, {b, c, e, f, h, i}} *)
|improve this answer|||||
$\endgroup$
2
$\begingroup$

Update

Transpose @ {l1, l2, l3} /. a:{__Symbol} :> Sequence @@ a

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

Original answer:

Append[First /@ #, Flatten[Last /@ #]] & [{l1, l2, l3}]

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

|improve this answer|||||
$\endgroup$
  • $\begingroup$ The desired output is {a, d, g, {b, c, e, f, h, i}} :D $\endgroup$ – Dr. belisarius Sep 25 '14 at 23:02
1
$\begingroup$

I would just add something for general case:

l1 = {a, h, u, {b, t, c}};
l2 = {d, e, t, y, {e, f}};
l3 = {g, {h, i}};

Append @@ ({Cases[#, _?(Head[#] =!= List &)], 
     Flatten[Cases[#, _List]]} &[Flatten[{l1, l2, l3}, 1]])

(*{a, h, u, d, e, t, y, g, {b, t, c, e, f, h, i}}*)
|improve this answer|||||
$\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.