20
\$\begingroup\$

Lists can contain lists and we have nested lists. But we don't like nested lists and want to flatten them. By flattening I mean create a list which does not contain any list, but elements of lists it contained before. I'll explain it more.

Input

An arbitrary size list which has the below properties:

  • it can contain integers
  • it can be empty
  • it can contain lists which have the same properties

These are some examples of valid lists:

[]
[1, 2, 46]
[[], []]
[[[14], [[5]]], 4, [2]]

Output

The output must be a list, which is empty or only contains numbers. It must not contain lists. The output must be the flattened version of the input.

  • all elements (beside empty lists) must be in the flattened version
  • the order matters

Test cases:

[[3],[3, [[6]]]] ->  [3, 3, 6]

[] -> []

[[], []] -> []

[[1, 4, 6], [1, [2, 67, [5, 7]]]] -> [1, 4, 6, 1, 2, 67, 5, 7]
\$\endgroup\$
11
  • 6
    \$\begingroup\$ Nice question, but it has already been asked before. I highly suggest using the Sandbox when posting new challenges next time. \$\endgroup\$
    – Seggan
    Jun 5, 2022 at 18:58
  • 5
    \$\begingroup\$ For what it is worth I think this is the better version of the challenge. The other version has a bunch of arbitrary restrictions that don't contribute to the challenge. \$\endgroup\$
    – Wheat Wizard
    Jun 5, 2022 at 18:59
  • 1
    \$\begingroup\$ @WheatWizard I don't see how the other one has a bunch of arbitrary restrictions. It just has some input constraints \$\endgroup\$
    – Seggan
    Jun 5, 2022 at 19:01
  • 5
    \$\begingroup\$ This is literally a built-in function in many if not most programming languages. How is this a code challenge? \$\endgroup\$ Jun 6, 2022 at 5:20
  • 5
    \$\begingroup\$ @SebastiaanvandenBroek It's certainly not a builtin in most programming languages. If you want to have fun choose a language where it's not, or choose not to use the builtin. \$\endgroup\$
    – Wheat Wizard
    Jun 6, 2022 at 11:49

28 Answers 28

17
\$\begingroup\$

Languages with built-ins

HBL, 0.5: - - Try it online!

Fig, ~0.823: f - Try it online!

flax, 1: F - Try it online!

Japt, 1: c - Try it online!

Jelly, 1: F - Try it online!

Vyxal, 1: f - Try it online!

05AB1E, 1: ˜ - Try it online!

Pyt, 1: Ƒ - Try it online!

J, 1: , - Try it online!

Pip, 2: FA - Try it online!

Pyth, 2: .n - Try it online!

Haskell + hgl, 3: rtc

Attache, 4: Flat - Try it online!

rSNBATWPL, 5: crush - Try it online!

R (almost), 6: unlist - Try it online!

Clojure, 7: flatten - Try it online!

jq, 7: flatten - Try it online!

Factor, 7: flatten - Try it online!

Haskell + free, 7: retract - Try it online!

Kotlin, 7: flatten - Try it online!

Mathematica, 7: Flatten - Try it online!

Prolog (SWI), 7: flatten - Try it online!

Racket, 7: flatten - Try it online!

Ruby, 7: flatten - Try it online!

Arturo, 7: flatten - Try it


Feel free to add to this community wiki. The below is a template to copy the code and links into to add to the above list.

[<language>](<language URL>), <byte-count>: `<code>` - [Try it online!](<interpreter url>)
\$\endgroup\$
1
12
\$\begingroup\$

Python 2, 39 bytes

f=lambda s:[s]*(s<f)or sum(map(f,s),[])

Attempt This Online!

Found independently but very similar to @xnor's answer to the linked question.

\$\endgroup\$
2
  • 3
    \$\begingroup\$ It could be argued that this is a slightly improved version of @xnor 's answer from the dupe thread. Kudos to you if you came up with it independently, otherwise maybe worth linking to the other answer? \$\endgroup\$
    – jezza_99
    Jun 6, 2022 at 7:48
  • 1
    \$\begingroup\$ @jezza_99 I did come up with it myself, but I will still link xnor's answer. Thanks for the pointer! \$\endgroup\$ Jun 6, 2022 at 7:58
8
\$\begingroup\$

sh + coreutils, 8 bytes

tr -d []

\$\endgroup\$
5
\$\begingroup\$

Whython, 31 bytes

f=lambda l:sum(map(f,l),[])?[l]

Explanation

f=                               # f is
  lambda                         # a function
         l:                      # that takes a single argument l:
               map(f,l)          # First, apply f to every element of l
           sum(        ,[])      # Then concatenate all the resulting lists together
                           ?     # If l is an integer, the map errors, so instead
                            [l]  # just wrap l in a singleton list and return that

Attempt This Online!

\$\endgroup\$
4
\$\begingroup\$

R, 22 bytes

\(x)as.list(unlist(x))

Attempt This Online!

unlist is an almost-built-in (see the CW answer) in R, as it doesn't correctly handle the empty lists - it returns NULL. Also, it returns a vector of values not a list, so we convert the result to list with as.list. Fortunately, as.list(NULL) results in an empty list as desired.


R, 40 38 bytes

Edit: -2 bytes thanks to @Dominic van Essen.

\(x)`if`(is.null(r<-unlist(x)),1[0],r)

Attempt This Online!

Outputs a vector (empty for input without any elements).

\$\endgroup\$
2
  • \$\begingroup\$ When the input list(s) contain some elements, this (and R's unlist function) returns vectors (not lists), here of integers . So it would be more consistent to return empty-vectors of integers when the input list(s) don't contain any elements. Luckily, this is 2 bytes shorter... \$\endgroup\$ Jun 6, 2022 at 11:09
  • 1
    \$\begingroup\$ @DominicvanEssen This gave me an idea... \$\endgroup\$
    – pajonk
    Jun 6, 2022 at 11:30
4
\$\begingroup\$

brainfuck, 350 bytes

-[<+>---]<++++++.[-]<,[>+<[>>+>+<<<-]>>>[<<<+>>>-]--[<->++++++]<-[>+>+<<<<[>>>>>+>+<<<<<<-]>>>>>>[<<<<<<+>>>>>>-]-[<->---]<------[<->[-]]<+<<<<[>>>>>+>+<<<<<<-]>>>>>>[<<<<<<+>>>>>>-]-[<->---]<--------[<->[-]]<[[-]<->]<[<<<.[>>>>+>+<<<<<-]>>>>>[<<<<<+>>>>>-]----[<-------->+]<[<<<<<[-]+>>>>>[-]]<[-]]<[-]<->]<[<<[>.>>][-]>>[-]]<,]>>-[<+>---]<++++++++.

Try it online!

Works by ignoring brackets inside the outermost list. It makes sure not to print a comma after another comma.

Can probably be improved.

\$\endgroup\$
3
\$\begingroup\$

R, 58 bytes

f=\(x,z=0[0]){for(i in x)z=c(z,`if`(is.list(i),f(i),i));z}

Attempt This Online!

'Roll your own' unlist-like function in R. Returns a vector containing all the elements of the input (nested-)list, or an empty numeric vector if the input doesn't contain any elements.

\$\endgroup\$
3
\$\begingroup\$

Python, 58 55 bytes

lambda l:[*map(int,re.findall('\d+',str(l)))]
import re

Attempt This Online!

Thought it was a bit cheeky using regex to flatten the list

-3 bytes thanks to @Dingus

\$\endgroup\$
2
3
\$\begingroup\$

C (gcc), 169 166 bytes

#include<ctype.h>
#define D isdigit(*c))
#define P putchar(
#define R while(*c&&!D c++;
main(char*c,int**v){c=v[1];P 91);R do{while(D P*c++);R P*c?44:93);}while(*c);}

Try it online!

\$\endgroup\$
4
  • \$\begingroup\$ Do the #defines for W, D and R actually save bytes? It's difficult for me to check without an online test link, but swapping the Ws, Ds and Rs in the code for their #defined strings seems to shorten the code to 149 bytes... \$\endgroup\$ Jun 9, 2022 at 19:25
  • \$\begingroup\$ @DominicvanEssen I didn't check it that thoroughly, but you forgot to replace W and D in #define R. It might be possible to find a shorter arrangement with some tweaks though. I'll add the TIO link too \$\endgroup\$
    – evanstar3
    Jun 9, 2022 at 20:04
  • 1
    \$\begingroup\$ Ah, yes, you're right! My mistake! I hadn't twigged to the nested #defines. Well done, and welcome to code golf! \$\endgroup\$ Jun 9, 2022 at 20:07
  • \$\begingroup\$ 160 bytes \$\endgroup\$
    – ceilingcat
    Jun 12, 2022 at 2:55
3
+300
\$\begingroup\$

Prolog (SWI), 45 bytes

[A|L]+B:-A+X,L+Y,append(X,Y,B).
[]+[].
A+[A].

Try it online!

Uses pattern matching to decompose and recursively call the function on the head and tail of the list.

Explanation

[A|L]+B:-                         # Match on list input with at least one input
         A+X,                     # Recursively call on the head of the list
             L+Y,                 # And on the tail
                 append(X,Y,B).   # And combine the results together
[]+[].  # If the element is just an empty list, return the same
A+[A].  # If it just a single element, return a singleton list
\$\endgroup\$
3
+100
\$\begingroup\$

Prolog (SWI), 62 38 bytes

Thanks @Steffan for a staggering -24 bytes!!!

L+X:-maplist(+,L,M),append(M,X);X=[L].

Try it online!

There's probably a builtin out there which flattens lists, but here's a non-builtin way of doing it.

\$\endgroup\$
6
  • \$\begingroup\$ yep: swi-prolog.org/pldoc/man?predicate=flatten/2 nice! \$\endgroup\$
    – naffetS
    Sep 3, 2022 at 16:08
  • \$\begingroup\$ [A,B]>>(A+B) can just be +, and you don't need parens around maplist(+,L,M),append(M,X). \$\endgroup\$
    – naffetS
    Sep 3, 2022 at 17:30
  • \$\begingroup\$ And you can remove is_list(L), - the goal will fail if it's not a list, resorting to X=[L] (also beats joking). Ends up in 38 bytes: Try it online! \$\endgroup\$
    – naffetS
    Sep 3, 2022 at 17:31
  • \$\begingroup\$ @Steffan wow you should post as your own answer, that's like way different from my answer. \$\endgroup\$
    – Aiden Chow
    Sep 3, 2022 at 23:06
  • \$\begingroup\$ it's the exact same answer but golfed lol. post it urself \$\endgroup\$
    – naffetS
    Sep 3, 2022 at 23:55
2
\$\begingroup\$

Charcoal, 53 bytes

⊞υθFυFιF⁼κ⁺⟦⟧κ⊞υκF⮌υ«≔⟦⟧ηWι⊞η⊟ιF⮌η¿⁼κ⁺⟦⟧κFκ⊞ιλ⊞ικ»⭆¹θ

Try it online! Link is to verbose version of code. Uses the same flattening code as I used in my answer to Inverted ragged list but I'll explain it in slightly more detail here.

⊞υθFυFιF⁼κ⁺⟦⟧κ⊞υκ

Push the input list and all of its sublists to the predefined empty list.

F⮌υ«

Loop over all of the sublists in reverse order i.e. deepest first.

≔⟦⟧ηWι⊞η⊟ι

Remove the elements of the sublist and push them to a temporary list.

F⮌η¿⁼κ⁺⟦⟧κFκ⊞ιλ⊞ικ

Loop over the elements of the temporary list in the order they were in the original sublist. For those elements that are sublists push their elements (which by now are just integers) to the sublist otherwise just push the integer element to the sublist.

»⭆¹θ

Pretty-print the final list so that you can see that it has been flattened.

\$\endgroup\$
2
\$\begingroup\$

Wolfram Language (Mathematica), 13 bytes

#~Level~{-1}&

Try it online!

Not the built-in. Returns all atomic expressions, in order.


Wolfram Language (Mathematica), 11 bytes

##&@@#0/@#&

Try it online!

Returns a Sequence instead of a List.

Wolfram Language (Mathematica), 6 bytes

#<>""&

Try it online!

Returns a StringJoin instead of a List, and an empty string when there are no elements (as StringJoin[] evaluates to "").

\$\endgroup\$
2
\$\begingroup\$

APL(Dyalog Unicode), 1 bytes SBCS

Try it on APLgolf!

\$\endgroup\$
3
  • \$\begingroup\$ I think it's 3 bytes, not 1 byte. \$\endgroup\$ Jun 7, 2022 at 8:43
  • 12
    \$\begingroup\$ Why not just add this to the list of built ins? \$\endgroup\$
    – Wheat Wizard
    Jun 7, 2022 at 9:03
  • \$\begingroup\$ @AmirrezaRiahi it uses a custom encoding where each character is one byte \$\endgroup\$
    – zoomlogo
    Jun 7, 2022 at 13:43
2
\$\begingroup\$

Scala, 75 bytes

def f(l:List[_]):List[_]=l.flatMap{case n:Int=>List(n)case p:List[_]=>f(p)}

My first Scala answer! With a lot of help from @user.
Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ Use Seq (a supertype of List) to save some bytes. Also, swapping the cases means you don't need to add :Int. \$\endgroup\$
    – user
    Sep 3, 2022 at 17:01
2
\$\begingroup\$

Javascript (node), 70 49 47 Bytes

f=(a,c=[])=>a.map(a=>a.map?f(a,c):c.push(a))&&c

Try it online!

\$\endgroup\$
5
  • 2
    \$\begingroup\$ -21 bytes, you can check whether a is an array by testing the truthiness of a.map, you also don't need the .flat() or |c in there. You've also got a trailing space :) \$\endgroup\$ Jun 7, 2022 at 4:55
  • \$\begingroup\$ Instead of ternary, you can write a?.map(i=>f(i,c))??c.push(a) -- Assuming ?. & ?? operators are supported/allowed. Saves 4 characters. \$\endgroup\$ Jun 8, 2022 at 11:59
  • 2
    \$\begingroup\$ @AjitPanigrahi That doesn't work, you instead need a.map?.(). Try it online! \$\endgroup\$
    – naffetS
    Jun 8, 2022 at 17:35
  • 1
    \$\begingroup\$ You can save a couple more bytes re-ordering the conditional check: Try it online! \$\endgroup\$ Jun 14, 2022 at 13:07
  • \$\begingroup\$ @DomHastings oooooh nice, just updated the answer, thanks! \$\endgroup\$
    – Asleepace
    Jun 14, 2022 at 19:04
2
\$\begingroup\$

BQN, 8 bytes

∾⍟(¯1+≡)

Try it here!

Thanks to @Razetime for 6 bytes saved!

Explanation

  • ...⍟(¯1+≡) repeat (depth - 1) times...
  • join (same effect as flattening 1 level)
\$\endgroup\$
3
  • \$\begingroup\$ ∾⍟(¯1+≡) without recursion (not checked on all cases) \$\endgroup\$
    – Razetime
    Jun 18, 2022 at 3:14
  • \$\begingroup\$ note that •Js can help you read JSON arrays into bqn arrays \$\endgroup\$
    – Razetime
    Jun 18, 2022 at 3:14
  • \$\begingroup\$ @Razetime thanks! Seems to work for all cases I've tested so far. \$\endgroup\$ Jun 18, 2022 at 4:58
2
\$\begingroup\$

Javascript, 96 83 bytes

f=a=>JSON.stringify(a).replace(/[\[\],]/g,' ').split(/\s/).filter(e=>e).map(e=>e-0)

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ You can save bytes by filtering for e=>e because '0' is truthy. And to convert a string to int you can use e-0 instead of parseInt \$\endgroup\$
    – Falco
    Jun 8, 2022 at 21:08
  • 2
    \$\begingroup\$ @Falco +e works, and also the [] in the regex don't need escaping if placed correctly. \$\endgroup\$
    – emanresu A
    Jun 9, 2022 at 6:31
2
\$\begingroup\$

PARI/GP, 34 bytes

f(a)=if(#a&&a!=b=concat(a),f(b),a)

Attempt This Online!

\$\endgroup\$
2
\$\begingroup\$

JavaScript (Node.js), 30 bytes

a=>eval(`[${a}]`).filter(x=>1)

Try it online!

JavaScript (Node.js), 39 bytes

a=>((a+'').match(/\d+/g)||[]).map(eval)

Try it online!

Assume no negative input

\$\endgroup\$
1
\$\begingroup\$

Uiua 0.11.0, 5 bytes SBCS

⍥/◇⊂∞

Try on Uiua Pad!

Takes a box array of box arrays and returns the flattened array. Sadly, does not work on box arrays.

Explanation

⍥/◇⊂∞
⍥   ∞ # repeat until constant
 /    # fold the list by...
  ◇⊂  # unboxing then joining together
\$\endgroup\$
1
\$\begingroup\$

C (gcc) -m32, 114 99 89 85 bytes

  • -15 bytes with help from @ceilingcat
*a;main(c,v){for(;v;c=0)printf(v?c?"[%s":",%s":"[]"+!c,v=strtok(c?1[a=v]:0,",[ ]"));}

Try it online!

\$\endgroup\$
0
1
\$\begingroup\$

Vyxal 3, 7 bytes

"\d+"y⌊

Try it Online! The one byte built in is boring, so I just get all the regex matches of numbers in the input list as a string and then convert back to numbers.

\$\endgroup\$
4
  • \$\begingroup\$ the two byte split on spaces and 4 byte split on commas dont work on empty lists \$\endgroup\$
    – pacman256
    Apr 25 at 12:28
  • \$\begingroup\$ The challenge says "integers" and doesn't specify that they're nonnegative, although all the examples are nonnegative. So you might need to add -? to your regex. \$\endgroup\$
    – DLosc
    Apr 25 at 17:47
  • \$\begingroup\$ can i return a list of strings \$\endgroup\$
    – pacman256
    Apr 25 at 18:11
  • \$\begingroup\$ I'm not the OP, so the best I can say is "Maybe ¯\_(ツ)_/¯"... You could try asking in a comment on the challenge. I've asked about the integer signs. \$\endgroup\$
    – DLosc
    Apr 25 at 18:22
1
\$\begingroup\$

Brachylog, 11 6 bytes

-5 bytes thanks to Fatalize

ℤg|↰ᵐc

Try it online!

Explanation

Brachylog has a flatten-list builtin, but 1) it only flattens by one level and 2) it only works on a list of lists, not a mixed-type list. So we need a recursive solution.

ℤg|↰ᵐc
ℤ       If the argument is an integer,
 g      wrap it in a singleton list
  |     Otherwise:
   ↰ᵐ   Recurse on each element of the list
     c  and flatten the result once
\$\endgroup\$
2
  • \$\begingroup\$ ℤg|↰ᵐc is the same idea but only 6 bytes. \$\endgroup\$
    – Fatalize
    Apr 29 at 7:52
  • \$\begingroup\$ Ohhh, recurse all the way down to integer arguments! Smart. \$\endgroup\$
    – DLosc
    Apr 29 at 15:37
0
\$\begingroup\$

Javascript 46 bytes

f=a=>(a+'').split(',').filter(x=>x).map(s=>+s)

Try it online!

Uses the trick that stringification of arrays unnests all arrays. After that empty elements need to be removed and the result mapped to integers.

\$\endgroup\$
0
\$\begingroup\$

sed, 29 bytes

s/[^0-9]+/,/g   #replace any string of non-num chars with a ,
s/,/[/          #replace first comma with [
s/,?$/]/        #replace last comma with ] or append ] if there isn't one

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Uiua, 11 bytes

⊜⋕±+17.$"_"

Try it!

Tbw’s solution is more practical and shorter but I thought this version was kinda fun. This converts the input to a string representation, adds 17 to each codepoint in order for 0..9 to get mapped to A..J. This leaves {, }, and as non-letters, so when passed to ± this effectively just gives a mask of the digits in the string. Finally the string is partitioned by this mask, with each segment getting parsed as an integer.

\$\endgroup\$
0
\$\begingroup\$

Go, 140 bytes

func f(s[]any)(o[]any){if len(s)<1{return}
for _,e:=range s{switch e:=e.(type){case[]any:o=append(o,f(e)...)
default:o=append(o,e)}}
return}

Attempt This Online!

Recursive function that returns a slice.

Goes through each element and switches on the type of the element. If it's a slice, recurse and append the result. Otherwise, append the element.

\$\endgroup\$

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.