10
$\begingroup$

I have nested list with sublists of varying lengths like this:

list={{a,b,c,d},{e,f},{g,h,i},{j},{k,l},{m,n,o}}

How can I join the 4th and 5th sublists based on their position to give me:

{{a,b,c,d},{e,f},{g,h,i},{j,k,l},{m,n,o}}

The closest I have managed to get is using:

FlattenAt[list, {{4}, {5}}]

But this gives:

{{a, b, c, d}, {e, f}, {g, h, i}, j, k, l, {m, n, o}}

Thanks in advance.

$\endgroup$
0

6 Answers 6

8
$\begingroup$

You could use SubsetMap (available from version 12.0), but since it requires you to return the same size you get, we could trick it by Hold and Nothing:

ReleaseHold @ SubsetMap[{Join @@ #, Hold @ Nothing} &, list, {4, 5}]

(* Out: {{a, b, c, d}, {e, f}, {g, h, i}, {j, k, l}, {m, n, o}} *)
$\endgroup$
1
  • $\begingroup$ This is great, works really well. Thanks! $\endgroup$
    – wmv
    Apr 21 at 15:09
8
$\begingroup$

Another approach using Delete, Extract and Insert:

Insert[Delete[list, #], Join @@ Extract[list, #], 4] & @@ {{{4}, {5}}}
(*{{a, b, c, d}, {e, f}, {g, h, i}, {j, k, l}, {m, n, o}}*)
$\endgroup$
7
$\begingroup$
ClearAll[spliceParts]
spliceParts =  Module[{l = #, p = Flatten @ #2},
  l[[First @ p]] =Flatten @ l[[p]]; l[[Rest @ p]] = Nothing; l] &;

Examples:

list = {{a, b, c, d}, {e, f}, {g, h, i}, {j}, {k, l}, {m, n, o}};

spliceParts[list, {{4}, {5}}]
{{a, b, c, d}, {e, f}, {g, h, i}, {j, k, l}, {m, n, o}}
spliceParts[list, { {4}, {5}, {2}}]
{{a, b, c, d}, {g, h, i}, {j, k, l, e, f}, {m, n, o}} 
$\endgroup$
4
$\begingroup$

Another way of doing it, albeit not elegant

Join[list[[1 ;; 3]], {Join[list[[4]], list[[5]]]}, {list[[6]]}]

out

$\endgroup$
3
$\begingroup$

Maybe we can do the 10 ways again, why not?

Hence, one way of doing it

TakeList[Flatten[list], {4, 2, 3, 3, 3}]

out1

$\endgroup$
3
  • 1
    $\begingroup$ The ten ways team! :) $\endgroup$ Apr 22 at 16:29
  • 1
    $\begingroup$ @E.Chan-López maybe we should have a banner next to questions with 10 or more answers :) Like level of awesomeness reached or something! $\endgroup$
    – bmf
    Apr 22 at 16:30
  • $\begingroup$ That's an excellent idea, @bmf! $\endgroup$ Apr 22 at 16:31
3
$\begingroup$

As ReplacePart "uses rules in the order given", ReplacePart may be used to Join sublists at the first position specified, and then remove all but the joined sublist:

ReplacePart[list, Flatten[{4:> Join[Sequence@@list[[{4,5}]]], Thread[{4,5}:> Nothing]}]]

{{a, b, c, d}, {e, f}, {g, h, i}, {j, k, l}, {m, n, o}}

As a 'pure' function:

ReplacePart[#1, Flatten[{#2[[1]]:> Join[Sequence@@#1[[##2]]], 
    Thread[##2:> Nothing]}]]&@@{list,{4,5}}

{{a, b, c, d}, {e, f}, {g, h, i}, {j, k, l}, {m, n, o}}


ReplacePart[#1, Flatten[{#2[[1]]:> Join[Sequence@@#1[[##2]]], 
    Thread[##2:> Nothing]}]]&@@{list,{5,4,1}

{{e, f}, {g, h, i}, {k, l, j, a, b, c, d}, {m, n, o}}

As a function:

f[lst_List,pos_List]:= ReplacePart[lst, Flatten[{pos[[1]]:> Join[Sequence@@lst[[pos]]], 
                         Thread[pos:> Nothing]}]]

Examples

f[list, {4,5}]

{{a, b, c, d}, {e, f}, {g, h, i}, {j, k, l}, {m, n, o}}

f[list, {6,1,3}]

{{e, f}, {j}, {k, l}, {m, n, o, a, b, c, d, g, h, i}}


list//f[#,Reverse@Range@Length@#]&//Catenate

{m, n, o, k, l, j, g, h, i, e, f, a, b, c, d}

where

list={{a, b, c, d}, {e, f}, {g, h, i},{j}, {k, l}, {m, n, o}};
$\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.