17
$\begingroup$

I've tried 3 methods but all failed to do that.

1st Method

Apply[Flatten, {1, {2, {3, 4}, 5}, 6}, {2}]

2nd Method

Map[Flatten, {1, {2, {3, 4}, 5}, 6}, {2}]

3rd Method

Flatten[{1, {2, {3, 4}, 5}, 6}, {2}]

I wanna get {1, {2, 3, 4, 5}, 6}

$\endgroup$
1
  • 6
    $\begingroup$ This problem is very underspecified. You might be asking "flatten the deepest level across everything" like {a, {b, c}, {d e}, f} -> {a,b,c,d,e,f}. You might be asking "assuming things are nested x -> (A x B), flatten the deepest" (not the case since presumably you want this to also work on {1,{2,3,4,5},6}). You might be asking "flatten the second element". You might be asking "flatten the second element by one level". You need to either specify the problem unambiguously, and/or provide like 10 all-encompassing edge-case examples (e.g. the empty list, etc.). $\endgroup$
    – ninjagecko
    Commented Jan 29, 2020 at 7:05

7 Answers 7

21
$\begingroup$
lst = {1, {2, {3, 4}, 5}, 6};
FlattenAt[lst, {2, 2}]

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

Also

Map[## & @@ # &, lst, {2}]

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

Replace[lst, List -> Sequence, {3}, Heads -> True]

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

And

☺ = ## & @@@ # & /@ # &;
☺ @ lst

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

$\endgroup$
1
  • 4
    $\begingroup$ Because this is an accepted answer, I suppose it is important to note a principal difference between FlattenAt[lst, {2, 2}] and the rest of the examples: FlattenAt flattens position, while, for example, Replace[lst, List -> Sequence, {3}, Heads -> True] flattens level. $\endgroup$ Commented Jan 29, 2020 at 13:16
14
$\begingroup$

We've got a few answers already, but here's my 2 cents:

Replace[l_List :> Flatten[l]] /@ {1, {2, {3, 4}, 5}, 6}

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

$\endgroup$
2
  • $\begingroup$ Is it possible to do this with Apply? $\endgroup$
    – kile
    Commented Jan 28, 2020 at 12:47
  • 3
    $\begingroup$ Using Apply doesn't make much sense with Flatten, since Flatten is a single-argument function (It does have an infrequently-used but useful second argument, but still). Apply is more useful for multi-argument functions like Join, List, and Plus. Technically, Flatten[{##}] & @@@ {1, {2, {3, 4}, 5}, 6} works, but only because 1 and 6 are atomic. It wouldn't work with, e.g., {Sin[1], {2, {3, 4}, 5}, Sin[6]}, so it's not a very good way to do what you want. $\endgroup$ Commented Jan 28, 2020 at 13:01
11
$\begingroup$

This will work:

l = {1, {2, {3, 4}, 5}, 6}
MapAt[Flatten, l, 2]

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

also:

# /. x_ /; Length[x] > 1 :> Flatten@x & /@ l

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

$\endgroup$
5
$\begingroup$
list = {1, {2, {3, 4}, 5}, 6};

If we want do modify list directly there is ApplyTo (since V 12.2)

list[[2]] //= Flatten;

list

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

A more traditional and explicit approach is

list /. {a_, b_, c_} :> {a, Flatten[b], c}

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

$\endgroup$
4
$\begingroup$

A couple more:

list = {1, {2, {3, 4}, 5}, 6};

Apply[## &, list, {2}]

Flatten[{##}] & @@@ list

Also if you are looking for specific level control consider levelspec in Replace. For example with:

rl = {a_, x__, z_} :> {a, {x} /. rl, z};
deep = Range[14] /. rl
{1, {2, {3, {4, {5, {6, {7, 8}, 9}, 10}, 11}, 12}, 13}, 14}

Then:

Replace[deep, {x__} :> x, {3, 5}]
{1, {2, {3, 4, 5, 6, {7, 8}, 9, 10, 11, 12}, 13}, 14}

Related:

$\endgroup$
3
$\begingroup$
lst[[2]]=Flatten@lst[[2]];lst

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

Also:

Delete[lst, {2,2,0}]

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

$\endgroup$
1
  • 1
    $\begingroup$ The Delete-solution is so different, nice and funny, that I would have posted it as another answer. $\endgroup$
    – eldo
    Commented Oct 11, 2023 at 19:08
2
$\begingroup$

Using Table:

Table[If[ListQ[#[[i]]], Flatten[#[[i]]], #[[i]]], {i, Length@#}] &@list

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

Also, using Cases:

Cases[list, x_ :> If[ListQ[x], Flatten@x, x]]

(*{1, {2, 3, 4, 5}, 6}*)
$\endgroup$

Not the answer you're looking for? Browse other questions tagged or ask your own question.