23
\$\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\$ Commented 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\$ Commented 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\$ Commented 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\$ Commented 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\$ Commented Jun 6, 2022 at 11:49

31 Answers 31

18
\$\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!

Nekomata, 1: V - Try it online!

MathGolf, 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!

Raku, 5: &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
  • 9
    \$\begingroup\$ Almost a built-in. Not sure if it should go there. \$\endgroup\$ Commented Jun 5, 2022 at 23:07
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\$ Commented 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\$ Commented Jun 6, 2022 at 7:58
11
\$\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\$
5
+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\$ Commented 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\$ Commented 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\$ Commented 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\$ Commented Sep 3, 2022 at 23:06
  • \$\begingroup\$ it's the exact same answer but golfed lol. post it urself \$\endgroup\$ Commented Sep 3, 2022 at 23:55
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\$ Commented Jun 6, 2022 at 11:09
  • 1
    \$\begingroup\$ @DominicvanEssen This gave me an idea... \$\endgroup\$ Commented 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\$
4
\$\begingroup\$

tinylisp, 82 bytes

(d _(q((H T)(i H(c(h H)(_(t H)T))(i(c()T)(i T(_(_()(h T))(t T))T)(c T(
(q((L)(_()L

Try it online!

The first line defines a helper function; the second line is an anonymous function that takes a list and flattens it.

The same idea but with a named function (F) as the solution is 83 bytes:

(d _(q((H T)(i H(c(h H)(_(t H)T))(F T
(d F(q((L)(i(c()L)(i L(_(F(h L))(t L))L)(c L(

Try it online!

Explanation

The 83-byte version is a bit easier to explain.

Helper function:

(d _(q((H T)(i H(c(h H)(_(t H)T))(F T)))))
(d _                                     ) ; Define _
    (q(                                ))  ; to be a function
       (H T)                               ; taking two lists, H and T
                                           ; (H is assumed to be already flattened)
            (i H                      )    ; If H is nonempty:
                (c              )          ;  Cons
                  (h H)                    ;  the first element of H
                       (_      )           ;  to a recursive call
                         (t H)             ;  on the rest of H
                              T            ;  and T unchanged
                                           ; Else:
                                 (F T)     ;  Call F on T, flattening it

Main function:

(d F(q((L)(i(c()L)(i L(_(F(h L))(t L))L)(c L())))))
(d F                                              ) ; Define F
    (q(                                         ))  ; to be a function
       (L)                                          ; taking one argument, L
          (i(c()L)                             )    ; If L is a list:
                  (i L                 )            ;  If L is nonempty:
                      (_             )              ;   Call _ on args:
                        (F     )                    ;    Recursively flatten
                          (h L)                     ;    first element of L
                                (t L)               ;    Rest of L
                                                    ;  Else (L is empty list):
                                      L             ;   Return L unchanged
                                                    ; Else (L is an integer):
                                        (c L())     ;  Wrap L in singleton list

The (c()L) idiom is a typechecking hack: consing anything to a list results in a nonempty list (truthy) but consing anything to an integer results in nil plus an error message (falsey).

\$\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
  • \$\begingroup\$ 49 with python 2 \$\endgroup\$ Commented Jun 8, 2022 at 17:38
  • \$\begingroup\$ and without regex, 42, and 41 with python 2 \$\endgroup\$ Commented Jun 8, 2022 at 17:49
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\$ Commented 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\$ Commented 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\$ Commented Jun 9, 2022 at 20:07
  • \$\begingroup\$ 160 bytes \$\endgroup\$ Commented 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\$
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\$

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\$ Commented 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\$ Commented 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\$ Commented Jun 8, 2022 at 11:59
  • 2
    \$\begingroup\$ @AjitPanigrahi That doesn't work, you instead need a.map?.(). Try it online! \$\endgroup\$ Commented Jun 8, 2022 at 17:35
  • 1
    \$\begingroup\$ You can save a couple more bytes re-ordering the conditional check: Try it online! \$\endgroup\$ Commented Jun 14, 2022 at 13:07
  • \$\begingroup\$ @DomHastings oooooh nice, just updated the answer, thanks! \$\endgroup\$ Commented 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\$ Commented Jun 18, 2022 at 3:14
  • \$\begingroup\$ note that •Js can help you read JSON arrays into bqn arrays \$\endgroup\$ Commented Jun 18, 2022 at 3:14
  • \$\begingroup\$ @Razetime thanks! Seems to work for all cases I've tested so far. \$\endgroup\$ Commented 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\$ Commented 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\$ Commented 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\$
2
\$\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\$ Commented Apr 29, 2024 at 7:52
  • \$\begingroup\$ Ohhh, recurse all the way down to integer arguments! Smart. \$\endgroup\$ Commented Apr 29, 2024 at 15:37
1
\$\begingroup\$

APL(Dyalog Unicode), 1 bytes SBCS

Try it on APLgolf!

\$\endgroup\$
1
  • 14
    \$\begingroup\$ Why not just add this to the list of built ins? \$\endgroup\$ Commented Jun 7, 2022 at 9:03
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\$ Commented Apr 25, 2024 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\$ Commented Apr 25, 2024 at 17:47
  • \$\begingroup\$ can i return a list of strings \$\endgroup\$ Commented Apr 25, 2024 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\$ Commented Apr 25, 2024 at 18:22
1
\$\begingroup\$

Setanta, 85 bytes

Determines whether a value is a list by looking at the first character of its string representation.

gniomh f(x){r:=[]ma go_teacs(x)[0]=='[' le i idir(0,fad@x)r+=f(x[i])no r=[x]toradh r}

try-setanta.ie link

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

JavaScript (Optional chaining), 22 bytes

f=x=>x.flatMap?.(f)||x

let f=x=>x.at?x.flatMap(f):x;
let t=x=>console.log(JSON.stringify(x), '->', JSON.stringify(f(x)));
t([[3],[3, [[6]]]]);t([]);t([[], []]);t([[1, 4, 6], [1, [2, 67, [5, 7]]]]);

JavaScript, 24 bytes

f=x=>x.at?x.flatMap(f):x

let f=x=>x.at?x.flatMap(f):x;
let t=x=>console.log(JSON.stringify(x), '->', JSON.stringify(f(x)));
t([[3],[3, [[6]]]]);t([]);t([[], []]);t([[1, 4, 6], [1, [2, 67, [5, 7]]]]);

Try them in your browser, or by using the snippets.

\$\endgroup\$
7
  • \$\begingroup\$ Welcome to code golf! We usually require that answers include a link to run the code online. Additionally, it seems your submission does not work correctly for all test cases. Once you fix it, you can use the edit button to change your submission to the new code :) \$\endgroup\$ Commented Feb 13 at 17:20
  • \$\begingroup\$ @Themoonisacheese There is no requirement to include a link. \$\endgroup\$ Commented Feb 13 at 17:53
  • 1
    \$\begingroup\$ Hi @Themoonisacheese, i omitted a tio.run link as none of the provided JavaScript runtimes supported optional chaining :) All test cases pass fine in the browser, do you know of any alternatives? \$\endgroup\$ Commented Feb 14 at 14:35
  • \$\begingroup\$ i stand corrected. for browser JS, you can include a stack snippet \$\endgroup\$ Commented Feb 14 at 15:00
  • \$\begingroup\$ Nice way to solve it, but FWIW, Array.prototype.flat can take a numeric argument for how many levels to flatten by. If given Infinity, it flattens the array completely. Therefore a=>a.flat(1/0) works for 14 bytes \$\endgroup\$ Commented Feb 15 at 15:12
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\$

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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.