# Join lists in a list of lists

What's the best way to join two consecutive lists in a list of lists ?

For example if I have the list

x = {{1}, {2}, {3}, {4}}


and I want to get in x

{{1}, {2, 3}, {4}}.


I want to join arbitrary positions.

Edit

I want to do this using the least amount of extra memory. Imagine that instead of having numbers I have big lists.

-
Could you explain why not just {{1, 2}, {3, 4}} or {{1, 2}, {3}, {4}} instead of {{1}, {2, 3}, {4}} ? –  Artes Jan 3 '13 at 22:43
Maybe give a more detailed example. Is it the 2nd and 3rd elements that should be joined or the 2nd and 3rd last elements that should be joined? ...or maybe the middle 2 elements joined?? To much ambiguity. –  Mike Honeychurch Jan 3 '13 at 23:04
what I mean by my comment is what result do you want from this list: {{1}, {2}, {3}, {4}, {5}} –  Mike Honeychurch Jan 3 '13 at 23:34
By using part I think the answer of 2013 is the most memory efficient. –  faysou Jan 4 '13 at 17:40
Your edit is important information since I'm sure some of these answers would be quite different if they knew up front that you are working with big lists rather than 4 integers. –  Mike Honeychurch Jan 5 '13 at 4:50

l = {{a}, {b}, {c}, {d}};
j[l_, from_, to_] := {Sequence @@ l[[1 ;; from - 1]], Join @@ l[[from ;; to]],
Sequence @@ l[[to + 1 ;;]]}

j[l, 2, 4]
(*
->{{a}, {b, c, d}}
*)

-
This is a bit terse. The OP may well need and deserve a little explanation to go with it. –  m_goldberg Jan 4 '13 at 2:13
@m_goldberg Feel free to improve the answer in any way you feel it should be done. The OP isn't asking for a Mma course, so it's up to you to interpret his/her need. –  belisarius Jan 4 '13 at 2:32
@m_goldberg Please don't take the above comment as derogatory. We deal here with users having from none to very advanced Mma knowledge. Faysal has been active here for a long time, so I guess he's able to untangle this piece of code –  belisarius Jan 4 '13 at 2:42
I got your point and didn't take any offense. Rather than edit your answer, I decided to offer one of my own, –  m_goldberg Jan 4 '13 at 3:46

Belisarius' answer works well if you are willing to work with indexes. If you prefer to work in terms of the list elements rather than their positions, here is a rule-based solution.

innerJoin[data : {{_} ..}, a_, b_] :=
data /. {x___, y : PatternSequence[{a}, ___, {b}], z___} :> {x, Flatten[{y}], z}

innerJoin[{{1}, {2}, {3}, {4}}, 2, 3]


{{1}, {2, 3}, {4}}

innerJoin[{{a}, {b}, {c}, {d}}, a, c]


{{a, b, c}, {d}}

Edit -- new and improved algorithm featuring the under appreciated PatternSequence :-)

-
Now with the OP's edit, I don't see how specifying the starting and ending elements would be a good idea if he wants to join 2 consecutive big lists. The Flatten would also fail if the elements are lists themselves –  Rojo Jan 5 '13 at 4:06
@Rojo. You're right but I didn't have that information when I wrote this answer. –  m_goldberg Jan 5 '13 at 4:19
list = {{1}, {2}, {3}, {4}}


I asked some questions in my comments but in the absence of clarification about what you want, i.e. will this always be applied to 4 element lists, why not just this:

list[[2]] = Flatten[list[[{2, 3}]]];
list[[3]] = Sequence[];
list

(* {{1}, {2, 3}, {4}} *)


or if you want to make it a function -- probably unnecessary because it is a straightforward two step process:

newList[list_List] := Module[{tmp = list}, tmp[[2]] = Flatten[tmp[[{2, 3}]]];
tmp[[3]] = Sequence[]; tmp]


Edit

Since you've said in your edit 4 hours ago that your actual example is big lists in place of the 4 numbers so you probably won't want to display output

list[[2]] = Flatten[list[[{2, 3}]]];
list[[3]] = Sequence[];
list;


or

list[[2]] = Flatten[list[[{2, 3}]]];
list = Delete[list, 3];

newList2[list_List] := Module[{tmp = list}, tmp[[2]] = Flatten[tmp[[{2, 3}]]];
Delete[tmp, 3]]

-
You should note that list[[3]] = Sequence[]; does not delete elements; evaluation must take place. Do that and you'll get my vote as I was going to suggest the same method. –  Mr.Wizard Jan 4 '13 at 21:39
If you mean that you have to evaluate list as a final step why is that problem? In all methods you have to undertake evaluation steps. In this one the final step is different to other methods. –  Mike Honeychurch Jan 4 '13 at 21:57
Reading his edit if he is actually working with large lists he probably won't want to display. I'll make a revision for that case. –  Mike Honeychurch Jan 4 '13 at 22:11
Mike, my point is that after making a list[[__]] = Sequence[] assignment you haven't deleted those elements (which I think you know). This could be very confusing if you then make further assignments with Part as you won't get what you (might) expect. A simple list = list; would do but so would Drop (more flexible than Delete). Anyway, +1. –  Mr.Wizard Jan 4 '13 at 23:23
@sebhofer IMHO that's far from a useless question. You can see the value by using my step function, e.g. list = Range@5; list[[3]] = Sequence[]; step[list]. I wrote that function to handle just such cases as this. –  Mr.Wizard Jan 5 '13 at 18:24

A bit more general version with Drop and ReplacePart:

list = List /@ Range@8
{from, to} = {3, 6}; (* specify first and last positions to be joined *)
ReplacePart[Drop[list, {from + 1, to}], from -> Join @@ Take[list, {from, to}]]

{{1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}}

{{1}, {2}, {3, 4, 5, 6}, {7}, {8}}


With ReplaceAll and Repeated:

list /. {x : Repeated[_, {from-1}], y : Repeated[_, {to-from+1}], z___} :> {x, Join@y, z}

{{1}, {2}, {3, 4, 5, 6}, {7}, {8}}

-