Flatten a list: Difference between revisions
Added Uiua solution
m (added whitespace before the TOC (table of contents).) |
(Added Uiua solution) |
||
(161 intermediate revisions by 56 users not shown) | |||
Line 1:
{{task}}
;Task:
Write a function to flatten the nesting in an arbitrary [[wp:List (computing)|list]] of values.
Your program should work on the equivalent of this list:
[[1], 2, [[3, 4], 5], [[[]]], [[[6]]], 7, 8, []]
Where the correct result would be the list:
[1, 2, 3, 4, 5, 6, 7, 8]
;Related task:
* [[Tree traversal]]
<br><br>
=={{header|8th}}==
<
\ take a list (array) and flatten it:
Line 15 ⟶ 20:
(
\ is it a number?
dup >kind
\ yes. so add to the list
r> swap a:push >r
Line 33 ⟶ 38:
. cr
bye
</syntaxhighlight>
{{out}}
[[1],2,[[3,4],5],[[[]]],[[[6]]],7,8,[]]<br>
Line 39 ⟶ 44:
=={{header|ACL2}}==
<
(cond ((null tr) nil)
((atom tr) (list tr))
(t (append (flatten (first tr))
(flatten (rest tr))))))</
=={{header|ActionScript}}==
<
var output:Array = new Array();
for (var i:uint = 0; i < input.length; i++) {
Line 59 ⟶ 64:
return output;
}
</syntaxhighlight>
=={{header|Ada}}==
nestable_lists.ads:
<syntaxhighlight lang="ada">generic
type Element_Type is private;
with function To_String (E : Element_Type) return String is <>;
package Nestable_Lists is
type Node_Kind is (Data_Node, List_Node);
type Node (Kind : Node_Kind);
type List is access Node;
type Node (Kind : Node_Kind) is record
Next : List;
case Kind is
when Data_Node =>
Data : Element_Type;
when List_Node =>
Sublist : List;
end case;
end record;
procedure Append (L : in out List; E : Element_Type);
procedure Append (L : in out List; N : List);
function Flatten (L : List) return List;
function New_List (E : Element_Type) return List;
function New_List (N : List) return List;
function To_String (L : List) return String;
end Nestable_Lists;</syntaxhighlight>
nestable_lists.adb:
<syntaxhighlight lang="ada">with Ada.Strings.Unbounded;
package body Nestable_Lists is
procedure Append (L : in out List; E : Element_Type) is
begin
if L = null then
L := new Node (Kind => Data_Node);
L.Data := E;
else
Append (L.Next, E);
end if;
end Append;
procedure Append (L : in out List; N : List) is
begin
if L = null then
L := new Node (Kind => List_Node);
L.Sublist := N;
else
Append (L.Next, N);
end if;
end Append;
function Flatten (L : List) return List is
Result : List;
Current : List := L;
Temp : List;
begin
while Current /= null loop
case Current.Kind is
when Data_Node =>
Append (Result, Current.Data);
when List_Node =>
Temp := Flatten (Current.Sublist);
while Temp /= null loop
Append (Result, Temp.Data);
Temp := Temp.Next;
end loop;
end case;
Current := Current.Next;
end loop;
return Result;
end Flatten;
function New_List (E : Element_Type) return List is
begin
return new Node'(Kind => Data_Node, Data => E, Next => null);
end New_List;
function New_List (N : List) return List is
begin
return new Node'(Kind => List_Node, Sublist => N, Next => null);
end New_List;
function To_String (L : List) return String is
Current : List := L;
Result : Ada.Strings.Unbounded.Unbounded_String;
begin
Ada.Strings.Unbounded.Append (Result, "[");
while Current /= null loop
case Current.Kind is
when Data_Node =>
Ada.Strings.Unbounded.Append
(Result, To_String (Current.Data));
when List_Node =>
Ada.Strings.Unbounded.Append
(Result, To_String (Current.Sublist));
end case;
if Current.Next /= null then
Ada.Strings.Unbounded.Append (Result, ", ");
end if;
Current := Current.Next;
end loop;
Ada.Strings.Unbounded.Append (Result, "]");
return Ada.Strings.Unbounded.To_String (Result);
end To_String;
end Nestable_Lists;</syntaxhighlight>
example usage:
<syntaxhighlight lang="ada">with Ada.Text_IO;
with Nestable_Lists;
procedure Flatten_A_List is
package Int_List is new Nestable_Lists
(Element_Type => Integer,
To_String => Integer'Image);
List : Int_List.List := null;
begin
Int_List.Append (List, Int_List.New_List (1));
Int_List.Append (List, 2);
Int_List.Append (List, Int_List.New_List (Int_List.New_List (3)));
Int_List.Append (List.Next.Next.Sublist.Sublist, 4);
Int_List.Append (List.Next.Next.Sublist, 5);
Int_List.Append (List, Int_List.New_List (Int_List.New_List (null)));
Int_List.Append (List, Int_List.New_List (Int_List.New_List
(Int_List.New_List (6))));
Int_List.Append (List, 7);
Int_List.Append (List, 8);
Int_List.Append (List, null);
declare
Flattened : constant Int_List.List := Int_List.Flatten (List);
begin
Ada.Text_IO.Put_Line (Int_List.To_String (List));
Ada.Text_IO.Put_Line (Int_List.To_String (Flattened));
end;
end Flatten_A_List;</syntaxhighlight>
Output:
<pre>[[ 1], 2, [[ 3, 4], 5], [[[]]], [[[ 6]]], 7, 8, []]
[ 1, 2, 3, 4, 5, 6, 7, 8]</pre>
=={{header|Aikido}}==
<
function flatten (list, result) {
foreach item list {
Line 86 ⟶ 239:
println("]")
</syntaxhighlight>
{{out}}
<pre>
Line 93 ⟶ 246:
=={{header|Aime}}==
<
show_list(list l)
{
integer i, k;
o_text("[");
i = 0;
while (i <
o_text(
if (
o_integer(
} else {
show_list
}
i += 1;
}
o_text("]");
}
list
flatten(list
{
if (__id(o) == INTEGER_ID) {
c.append(o);
l_ucall(o, flatten, 1, c);
}
}
Line 164 ⟶ 284:
list l;
show_list(l);
o_byte('\n');
show_list(flatten(list(), l));
o_byte('\n');
return 0;
}</
{{out}}
<pre>
Line 190 ⟶ 310:
Flattening is built in to all of Algol68's ''transput'' routines. The following example also uses ''widening'', where scalars are converted into arrays.
<
[][][]INT list = ((1), 2, ((3,4), 5), ((())), (((6))), 7, 8, ());
print((list, new line))
)</
{{out}}
<pre>
+1 +2 +3 +4 +5 +6 +7 +8
</pre>
=={{header|APL}}==
=== Dyalog APL ===
Flatten is a primitive in APL, named enlist
<syntaxhighlight lang="apl">∊</syntaxhighlight>
{{out}}
<pre> ∊((1) 2 ((3 4) 5) (((⍬))) (((6))) 7 8 (⍬))
1 2 3 4 5 6 7 8</pre>
=={{header|AppleScript}}==
<
on my_flatten(aList)
end my_flatten
</syntaxhighlight>
Or, to make more productive use of the language (where "efficiency" is a function of the scripter's time, rather than the machine's) we can express this in terms of a generic '''concatMap''':
{{trans|JavaScript}}
<syntaxhighlight lang="applescript">-- flatten :: Tree a -> [a]
on flatten(t)
if class of t is list then
concatMap(
else
t
Line 227 ⟶ 355:
end flatten
--------------------------- TEST ---------------------------
on run
Line 236 ⟶ 364:
-------------------- GENERIC
-- concatMap :: (a -> [b]) -> [a] -> [b]
on concatMap(f, xs)
set lng to length of xs
repeat with i from 1 to lng
end repeat
end tell
return lst
end
-- Lift 2nd class handler function into 1st class script wrapper
-- mReturn :: Handler -> Script
else
script
property |λ| : f
end
end mReturn</syntaxhighlight>
{{Out}}
<syntaxhighlight lang="applescript">{1, 2, 3, 4, 5, 6, 7, 8}</syntaxhighlight>
It can be more efficient to build just one list by appending items to it than to proliferate lists using concatenation:
<syntaxhighlight lang="applescript">on flatten(theList)
property flatList : {}
-- Recursive handler dealing with the current (sub)list.
on flttn(thisList)
script p
property l : thisList
end script
repeat with i from 1 to (count thisList)
set thisItem to item i of p's l
if (thisItem's class is list) then
flttn(thisItem)
else
set end of my flatList to thisItem
end if
end repeat
end flttn
end script
if (theList's class is not list) then return theList
o's flttn(theList)
return o's flatList
end flatten</syntaxhighlight>
=={{header|Arturo}}==
<syntaxhighlight lang="rebol">print flatten [[1], 2, [[3, 4], 5], [[[]]], [[[6]]], 7, 8, []]</syntaxhighlight>
{{out}}
<pre>
=={{header|AutoHotkey}}==
Line 289 ⟶ 435:
AutoHotkey doesn't have built in list data type.
This examples simulates a list in a tree type object and flattens that tree.
<
, 2, 5), 4, object(1, object(1, object(1, object()))), 5
, object(1, object(1, 6)), 6, 7, 7, 8, 9, object())
Line 340 ⟶ 486:
}
return flat
}</
=={{header|BASIC}}==
==={{header|BaCon}}===
BaCon has the concept of delimited strings, which may contain delimited strings within delimited strings etc. Such nested delimited strings must be surrounded by (escaped) double quotes in order to avoid their delimiter messing up operations on higher level delimited strings. However, from functional point of view, a delimited string is the same as a regular list. The special function FLATTEN$ can actually flatten out lists within lists. The last SORT$ in the program below makes sure no empty items remain in the list.
<syntaxhighlight lang="qbasic">OPTION COLLAPSE TRUE
lst$ = "\"1\",2,\"\\\"3,4\\\",5\",\"\\\"\\\\\"\\\\\"\\\"\",\"\\\"\\\\\"6\\\\\"\\\"\",7,8,\"\""
PRINT lst$
REPEAT
lst$ = FLATTEN$(lst$)
UNTIL AMOUNT(lst$, ",") = AMOUNT(FLATTEN$(lst$), ",")
PRINT SORT$(lst$, ",")</syntaxhighlight>
{{out}}
<pre>"1",2,"\"3,4\",5","\"\\"\\"\"","\"\\"6\\"\"",7,8,""
1,2,3,4,5,6,7,8</pre>
==={{header|BASIC256}}===
{{trans|FreeBASIC}}
<syntaxhighlight lang="basic256">sComma = "": sFlatter = ""
sString = "[[1], 2, [[3,4], 5], [[[]]], [[[6]]], 7, 8 []]"
For siCount = 1 To Length(sString)
If Instr("[] ,", Mid(sString, siCount, 1)) = 0 Then
sFlatter = sFlatter & sComma & Mid(sString, siCount, 1)
sComma = ", "
End If
Next siCount
Print "["; sFlatter; "]"
End</syntaxhighlight>
{{out}}
<pre>Igual que la entrada de FreeBASIC.</pre>
==={{header|Chipmunk Basic}}===
{{works with|Chipmunk Basic|3.6.4}}
{{works with|QBasic}}
<syntaxhighlight lang="qbasic">10 cls
20 sstring$ = "[[1], 2, [[3,4], 5], [[[]]], [[[6]]], 7, 8 []]"
30 for sicount = 1 to len(sstring$)
40 if instr("[] ,",mid$(sstring$,sicount,1)) = 0 then
50 sflatter$ = sflatter$+scomma$+mid$(sstring$,sicount,1)
60 scomma$ = ", "
70 endif
80 next sicount
90 print "[";sflatter$;"]"
100 end</syntaxhighlight>
==={{header|FreeBASIC}}===
{{trans|Gambas}}
<syntaxhighlight lang="freebasic">Dim As String sComma, sString, sFlatter
Dim As Short siCount
sString = "[[1], 2, [[3,4], 5], [[[]]], [[[6]]], 7, 8 []]"
For siCount = 1 To Len(sString)
If Instr("[] ,", Mid(sString, siCount, 1)) = 0 Then
sFlatter += sComma + Mid(sString, siCount, 1)
sComma = ", "
End If
Next siCount
Print "["; sFlatter; "]"
Sleep</syntaxhighlight>
{{out}}
<pre>[1, 2, 3, 4, 5, 6, 7, 8]</pre>
==={{header|Gambas}}===
'''[https://gambas-playground.proko.eu/?gist=1c0157ce2b7eab99ba4e784e183ba474 Click this link to run this code]'''
<syntaxhighlight lang="gambas">'Code 'borrowed' from Run BASIC
Public Sub Main()
Dim sComma, sString, sFlatter As String
Dim siCount As Short
sString = "[[1], 2, [[3,4], 5], [[[]]], [[[6]]], 7, 8 []]"
For siCount = 1 To Len(sString)
If InStr("[] ,", Mid$(sString, siCount, 1)) = 0 Then
sFlatter = sFlatter & sComma & Mid(sString, siCount, 1)
sComma = ","
End If
Next
Print "["; sFlatter; "]"
End</syntaxhighlight>
Output:
<pre>[1,2,3,4,5,6,7,8]</pre>
==={{header|GW-BASIC}}===
{{works with|Chipmunk Basic}}
{{works with|QBasic}}
<syntaxhighlight lang="qbasic">10 CLS
20 SSTRING$ = "[[1], 2, [[3,4], 5], [[[]]], [[[6]]], 7, 8 []]"
30 FOR SICOUNT = 1 TO LEN(SSTRING$)
40 IF INSTR("[] ,",MID$(SSTRING$,SICOUNT,1)) = 0 THEN SFLATTER$ = SFLATTER$+SCOMMA$+MID$(SSTRING$,SICOUNT,1): SCOMMA$ = ", "
50 NEXT SICOUNT
60 PRINT "[";SFLATTER$;"]"
70 END</syntaxhighlight>
==={{header|MSX Basic}}===
{{works with|QBasic}}
{{works with|Chipmunk Basic}}
{{works with|GW-BASIC}}
<syntaxhighlight lang="qbasic">10 CLS
20 S$ = "[[1], 2, [[3,4], 5], [[[]]], [[[6]]], 7, 8 []]"
30 FOR SICOUNT = 1 TO LEN(S$)
40 IF INSTR("[] ,",MID$(S$,SICOUNT,1)) = 0 THEN SFLATTER$ = SFLATTER$+SCOMMA$+MID$(S$,SICOUNT,1): SCOMMA$ = ", "
50 NEXT SICOUNT
60 PRINT "[";SFLATTER$;"]"
70 END</syntaxhighlight>
==={{header|PureBasic}}===
<syntaxhighlight lang="purebasic">Structure RCList
Value.i
List A.RCList()
EndStructure
Procedure Flatten(List A.RCList())
ResetList(A())
While NextElement(A())
With A()
If \Value
Continue
Else
ResetList(\A())
While NextElement(\A())
If \A()\Value: A()\Value=\A()\Value: EndIf
Wend
EndIf
While ListSize(\A()): DeleteElement(\A()): Wend
If Not \Value: DeleteElement(A()): EndIf
EndWith
Wend
EndProcedure</syntaxhighlight>
Set up the MD-List & test the Flattening procedure.
<syntaxhighlight lang="purebasic">;- Set up two lists, one multi dimensional and one 1-D.
NewList A.RCList()
;- Create a deep list
With A()
AddElement(A()): AddElement(\A()): AddElement(\A()): \A()\Value=1
AddElement(A()): A()\Value=2
AddElement(A()): AddElement(\A()): \A()\Value=3
AddElement(\A()): \A()\Value=4
AddElement(A()): AddElement(\A()): \A()\Value=5
AddElement(A()): AddElement(\A()): AddElement(\A()): AddElement(\A())
AddElement(A()): AddElement(\A()): AddElement(\A()): \A()\Value=6
AddElement(A()): A()\Value=7
AddElement(A()): A()\Value=8
AddElement(A()): AddElement(\A()): AddElement(\A())
EndWith
Flatten(A())
;- Present the result
If OpenConsole()
Print("Flatten: [")
ForEach A()
Print(Str(A()\Value))
If ListIndex(A())<(ListSize(A())-1)
Print(", ")
Else
PrintN("]")
EndIf
Next
Print(#CRLF$+"Press ENTER to quit"): Input()
EndIf</syntaxhighlight><pre>Flatten: [1, 2, 4, 5, 6, 7, 8]</pre>
==={{header|QBasic}}===
{{works with|QBasic|1.1}}
{{works with|QuickBasic|4.5}}
<syntaxhighlight lang="qbasic">sString$ = "[[1], 2, [[3,4], 5], [[[]]], [[[6]]], 7, 8 []]"
FOR siCount = 1 TO LEN(sString$)
IF INSTR("[] ,", MID$(sString$, siCount, 1)) = 0 THEN
sFlatter$ = sFlatter$ + sComma$ + MID$(sString$, siCount, 1)
sComma$ = ", "
END IF
NEXT siCount
PRINT "["; sFlatter$; "]"
END</syntaxhighlight>
==={{header|Run BASIC}}===
{{incorrect|Run BASIC| The task is not in string translation but in list translation.}}
<syntaxhighlight lang="runbasic">n$ = "[[1], 2, [[3,4], 5], [[[]]], [[[6]]], 7, 8 []]"
for i = 1 to len(n$)
if instr("[] ,",mid$(n$,i,1)) = 0 then
flatten$ = flatten$ + c$ + mid$(n$,i,1)
c$ = ","
end if
next i
print "[";flatten$;"]"</syntaxhighlight>
{{out}}
<pre>[1,2,3,4,5,6,7,8]</pre>
==={{header|TI-89 BASIC}}===
There is no nesting of lists or other data structures in TI-89 BASIC, short of using variable names as pointers.
==={{header|True BASIC}}===
<syntaxhighlight lang="qbasic">LET sstring$ = "[[1], 2, [[3,4], 5], [[[]]], [[[6]]], 7, 8 []]"
FOR sicount = 1 TO LEN(sstring$)
IF pos("[] ,",(sstring$)[sicount:sicount+1-1]) = 0 THEN
LET sflatter$ = sflatter$ & scomma$ & (sstring$)[sicount:sicount+1-1]
LET scomma$ = ", "
END IF
NEXT sicount
PRINT "["; sflatter$; "]"
END</syntaxhighlight>
==={{header|XBasic}}===
{{works with|Windows XBasic}}
<syntaxhighlight lang="xbasic">PROGRAM "Flatten a list"
DECLARE FUNCTION Entry ()
FUNCTION Entry ()
n$ = "[[1], 2, [[3,4], 5], [[[]]], [[[6]]], 7, 8 []]"
FOR i = 1 TO LEN(n$)
IF INSTR("[] ,",MID$(n$,i,1)) = 0 THEN
flatten$ = flatten$ + c$ + MID$(n$,i,1)
c$ = ", "
END IF
NEXT i
PRINT "[";flatten$;"]"
END FUNCTION
END PROGRAM</syntaxhighlight>
{{out}}
<pre>[1, 2, 3, 4, 5, 6, 7, 8]</pre>
==={{header|Yabasic}}===
{{trans|FreeBASIC}}
<syntaxhighlight lang="yabasic">sString$ = "[[1], 2, [[3,4], 5], [[[]]], [[[6]]], 7, 8 []]"
For siCount = 1 To Len(sString$)
If Instr("[] ,", Mid$(sString$, siCount, 1)) = 0 Then
sFlatter$ = sFlatter$ + sComma$ + Mid$(sString$, siCount, 1)
sComma$ = ", "
End If
Next siCount
Print "[", sFlatter$, "]"
End</syntaxhighlight>
{{out}}
<pre>Igual que la entrada de FreeBASIC.</pre>
==={{header|ZX Spectrum Basic}}===
{{incorrect|ZX Spectrum Basic| The task is not in string translation but in list translation.}}
<syntaxhighlight lang="zxbasic">10 LET f$="["
20 LET n$="[[1], 2, [[3,4], 5], [[[]]], [[[6]]], 7, 8 []]"
30 FOR i=2 TO (LEN n$)-1
40 IF n$(i)>"/" AND n$(i)<":" THEN LET f$=f$+n$(i): GO TO 60
50 IF n$(i)="," AND f$(LEN f$)<>"," THEN LET f$=f$+","
60 NEXT i
70 LET f$=f$+"]": PRINT f$</syntaxhighlight>
=={{header|BQN}}==
<syntaxhighlight lang="bqn">Enlist ← {(∾𝕊¨)⍟(1<≡)⥊𝕩}</syntaxhighlight>
{{out}}
<pre>
Enlist ⟨⟨1⟩, 2, ⟨⟨3, 4⟩, 5⟩, ⟨⟨⟨⟩⟩⟩, ⟨⟨⟨6⟩⟩⟩, 7, 8, ⟨⟩⟩
⟨ 1 2 3 4 5 6 7 8 ⟩
</pre>
=={{header|Bracmat}}==
Line 351 ⟶ 764:
A list that should not be flattened upon evaluation can be separated with dots.
<
( (myList = ((1), 2, ((3,4), 5), ((())), (((6))), 7, 8, ()))
& put$("Unevaluated:")
Line 359 ⟶ 772:
& lst$myList
)
</syntaxhighlight>
=={{header|Brat}}==
<
true? my.empty?
{ [] }
Line 373 ⟶ 786:
list = [[1], 2, [[3,4], 5], [[[]]], [[[6]]], 7, 8, []]
p "List: #{list}"
p "Flattened: #{list.flatten}"</
=={{header|Burlesque}}==
Line 380 ⟶ 793:
until the Block does not contain Blocks anymore.
<
blsq ) {{1} 2 {{3 4} 5} {{{}}} {{{6}}} 7 8 {}}{\[}{)to{"Block"==}ay}w!
{1 2 3 4 5 6 7 8}
</syntaxhighlight>
=={{header|C}}==
<
#include <stdlib.h>
#include <string.h>
Line 503 ⟶ 916:
/* delete_list(l); delete_list(flat); */
return 0;
}</
{{out}}
<pre>Nested: [[1], 2, [[3, 4], 5], [[[]]], [[[6]]], 7, 8, []]
Flattened: [1, 2, 3, 4, 5, 6, 7, 8]</pre>
=={{header|C sharp|C#}}==
{{works with|C sharp|C#|3+}}
Actual Workhorse code
<syntaxhighlight lang="csharp">
using System;
using System.Collections;
using System.Linq;
namespace RosettaCodeTasks
{
static class FlattenList
{
public static ArrayList Flatten(this ArrayList List)
{
ArrayList NewList = new ArrayList ( );
NewList.AddRange ( List );
while ( NewList.OfType<ArrayList> ( ).Count ( ) > 0 )
{
int index = NewList.IndexOf ( NewList.OfType<ArrayList> ( ).ElementAt ( 0 ) );
ArrayList Temp = (ArrayList)NewList[index];
NewList.RemoveAt ( index );
NewList.InsertRange ( index, Temp );
}
return NewList;
}
}
}
</syntaxhighlight>
Method showing population of arraylist and usage of flatten method
<syntaxhighlight lang="csharp">
using System;
using System.Collections;
namespace RosettaCodeTasks
{
class Program
{
static void Main ( string[ ] args )
{
ArrayList Parent = new ArrayList ( );
Parent.Add ( new ArrayList ( ) );
((ArrayList)Parent[0]).Add ( 1 );
Parent.Add ( 2 );
Parent.Add ( new ArrayList ( ) );
( (ArrayList)Parent[2] ).Add ( new ArrayList ( ) );
( (ArrayList)( (ArrayList)Parent[2] )[0] ).Add ( 3 );
( (ArrayList)( (ArrayList)Parent[2] )[0] ).Add ( 4 );
( (ArrayList)Parent[2] ).Add ( 5 );
Parent.Add ( new ArrayList ( ) );
( (ArrayList)Parent[3] ).Add ( new ArrayList ( ) );
( (ArrayList)( (ArrayList)Parent[3] )[0] ).Add ( new ArrayList ( ) );
Parent.Add ( new ArrayList ( ) );
( (ArrayList)Parent[4] ).Add ( new ArrayList ( ) );
( (ArrayList)( (ArrayList)Parent[4] )[0] ).Add ( new ArrayList ( ) );
( (ArrayList)( (ArrayList)( (ArrayList)( (ArrayList)Parent[4] )[0] )[0] ) ).Add ( 6 );
Parent.Add ( 7 );
Parent.Add ( 8 );
Parent.Add ( new ArrayList ( ) );
foreach ( Object o in Parent.Flatten ( ) )
{
Console.WriteLine ( o.ToString ( ) );
}
}
}
}
</syntaxhighlight>
{{works with|C sharp|C#|4+}}
<syntaxhighlight lang="csharp">
public static class Ex {
public static List<object> Flatten(this List<object> list) {
var result = new List<object>();
foreach (var item in list) {
if (item is List<object>) {
result.AddRange(Flatten(item as List<object>));
} else {
result.Add(item);
}
}
return result;
}
public static string Join<T>(this List<T> list, string glue) {
return string.Join(glue, list.Select(i => i.ToString()).ToArray());
}
}
class Program {
static void Main(string[] args) {
var list = new List<object>{new List<object>{1}, 2, new List<object>{new List<object>{3,4}, 5}, new List<object>{new List<object>{new List<object>{}}}, new List<object>{new List<object>{new List<object>{6}}}, 7, 8, new List<object>{}};
Console.WriteLine("[" + list.Flatten().Join(", ") + "]");
Console.ReadLine();
}
}
</syntaxhighlight>
=={{header|C++}}==
<
#include <boost/any.hpp>
Line 531 ⟶ 1,055:
++current;
}
}</
Use example:
Line 539 ⟶ 1,063:
Also, there's no standard way to output this type of list,
so some output code is added as well.
<
#include <iostream>
Line 642 ⟶ 1,166:
print_list(list);
std::cout << "\n";
}</
{{out}}
<pre>
Line 648 ⟶ 1,172:
[1, 2, 3, 4, 5, 6, 7, 8]
</pre>
=={{header|Ceylon}}==
<
"Lazily flatten nested streams"
{Anything*} flatten({Anything*} stream)
Line 773 ⟶ 1,186:
print(list);
print(flatten(list).sequence());
}</
{{out}}
<pre>
Line 782 ⟶ 1,195:
=={{header|Clojure}}==
The following returns a lazy sequence of the flattened data structure.
<
(lazy-seq
(when-let [s (seq coll)]
(if (coll? (first s))
(concat (flatten (first s)) (flatten (rest s)))
(cons (first s) (flatten (rest s)))))))</
The built-in flatten is implemented as:
<
(filter (complement sequential?)
(rest (tree-seq sequential? seq x))))</
=={{header|CoffeeScript}}==
<
flatten = (arr) ->
arr.reduce ((xs, el) ->
Line 807 ⟶ 1,220:
list = [[1], 2, [[3,4], 5], [[[]]], [[[6]]], 7, 8, []]
console.log flatten list
</syntaxhighlight>
Ouput:
<syntaxhighlight lang="text">
> coffee foo.coffee
[ 1, 2, 3, 4, 5, 6, 7, 8 ]
</syntaxhighlight>
=={{header|Common Lisp}}==
<
(cond ((null structure) nil)
((atom structure) (list structure))
(t (mapcan #'flatten structure))))</
or, from Paul Graham's OnLisp,
<
(defun flatten (ls)
(labels ((mklist (x) (if (listp x) x (list x))))
(mapcan #'(lambda (x) (if (atom x) (mklist x) (flatten x))) ls)))
</syntaxhighlight>
Note that since, in Common Lisp, the empty list, boolean false and <code>nil</code> are the same thing, a tree of <code>nil</code> values cannot be flattened; they will disappear.
A third version that is recursive, imperative, and reasonably fast.
<
(let (result)
(labels ((grep (obj)
Line 839 ⟶ 1,252:
(grep (first obj))))))
(grep obj)
result)))</
The following version is tail recursive and functional.
<
(cond ((consp x) (flatten (rest x) (cons (first x) stack) out))
(x (flatten (first stack) (rest stack) (cons x out)))
(stack (flatten (first stack) (rest stack) out))
(t out)))</
The next version is imperative, iterative and does not make use of a stack. It is faster than the versions given above.
<
(do* ((result (list obj))
(node result))
Line 856 ⟶ 1,269:
(when (cdar node) (push (cdar node) (cdr node)))
(setf (car node) (caar node)))
(t (setf node (cdr node))))))</
The above implementations of flatten give the same output on nested proper lists.
{{Out}}
Line 881 ⟶ 1,294:
Which version is suitable for a given problem depends of course on the nature of the problem.
=={{header|Crystal}}==
<syntaxhighlight lang="ruby">
[[1], 2, [[3, 4], 5], [[[] of Int32]], [[[6]]], 7, 8, [] of Int32].flatten()
</syntaxhighlight>
<syntaxhighlight lang="bash">
[1, 2, 3, 4, 5, 6, 7, 8]
</syntaxhighlight>
=={{header|D}}==
Instead of a Java-like class-based version, this version minimizes heap activity using a tagged union.
<
struct TreeList(T) {
Line 926 ⟶ 1,347:
l.writeln;
l.flatten.writeln;
}</
{{out}}
<pre>[[1], 2, [[3, 4], 5], [[[]]], [[[6]]], 7, 8, []]
Line 932 ⟶ 1,353:
===With an Algebraic Data Type===
A shorter and more cryptic version.
<
alias T = Algebraic!(int, This[]);
Line 950 ⟶ 1,371:
T( T[].init )
]).flatten.writeln;
}</
{{out}}
[1, 2, 3, 4, 5, 6, 7, 8]
=={{header|Déjà Vu}}==
<
for i in copy:
i
Line 965 ⟶ 1,386:
!. flatten [ [ 1 ] 2 [ [ 3 4 ] 5 ] [ [ [] ] ] [ [ [ 6 ] ] ] 7 8 [] ]</
{{out}}
<pre>[ 1 2 3 4 5 6 7 8 ]</pre>
Line 971 ⟶ 1,392:
=={{header|E}}==
<
def flat := [].diverge()
def recur(x) {
Line 981 ⟶ 1,402:
recur(nested)
return flat.snapshot()
}</
<
# value: [1, 2, 3, 4, 5, 6, 7, 8]</
=={{header|EchoLisp}}==
The built-in '''(flatten list)''' is defined as follows:
<
(define (fflatten l)
(cond
Line 1,016 ⟶ 1,437:
→ ((4) (5 5 5) (6 6) (7) (8) (7 7 7) (9))
</syntaxhighlight>
=={{header|Ela}}==
Line 1,022 ⟶ 1,443:
This implementation can flattern any given list:
<
flat = flat' []
Line 1,030 ⟶ 1,451:
| else = x :: flat' n xs
flat xs</
{{out}}
Line 1,037 ⟶ 1,458:
An alternative solution:
<
flat (x::xs)
| x is List = flat x ++ flat xs
| else = x :: flat xs</
=={{header|Elixir}}==
<
defmodule RC do
def flatten([]), do: []
Line 1,056 ⟶ 1,477:
# Library function
IO.inspect List.flatten(list)
</syntaxhighlight>
{{out}}
<pre>
Line 1,065 ⟶ 1,486:
=={{header|Elm}}==
<
import Graphics.Element exposing (show)
Line 1,093 ⟶ 1,514:
main =
show (flatten tree)
</syntaxhighlight>
=={{header|Emacs Lisp}}==
<syntaxhighlight lang="lisp">(defun flatten (mylist)
(cond
((null mylist) nil)
((atom mylist) (list mylist))
(t
(append (flatten (car mylist)) (flatten (cdr mylist))))))</syntaxhighlight>
The flatten-tree function was added in Emacs 27.1 or earlier.
<syntaxhighlight lang="lisp">
(flatten-tree mylist)
</syntaxhighlight>
=={{header|Erlang}}==
There's a standard function (lists:flatten/1) that does it more efficiently, but this is the cleanest implementation you could have;
<
flatten([H|T]) -> flatten(H) ++ flatten(T);
flatten(H) -> [H].</
=={{header|Euphoria}}==
{{works with|Euphoria|4.0.0}}
<
function flatten( object s )
Line 1,133 ⟶ 1,558:
? a
? flatten(a)</
{{out}}
<pre>{
Line 1,158 ⟶ 1,583:
=={{header|F_Sharp|F#}}==
As with Haskell and OCaml we have to define our list as an algebraic data type, to be strongly typed:
<
| I of 'a // leaf Item
| L of 'a ll list // ' <- confine the syntax colouring confusion
Line 1,169 ⟶ 1,594:
printfn "%A" (flatten [L([I(1)]); I(2); L([L([I(3);I(4)]); I(5)]); L([L([L([])])]); L([L([L([I(6)])])]); I(7); I(8); L([])])
// -> [1; 2; 3; 4; 5; 6; 7; 8]</
An alternative approach with List.collect
and the same data type. Note that flatten operates on all deepLists (ll) and atoms (I) are "flatened" to lists.
<
let rec flatten =
function
Line 1,183 ⟶ 1,608:
// -> [1; 2; 3; 4; 5; 6; 7; 8]
</syntaxhighlight>
=={{header|Factor}}==
Line 1,192 ⟶ 1,617:
=={{header|Fantom}}==
<
class Main
{
Line 1,218 ⟶ 1,643:
}
}
</syntaxhighlight>
=={{header|Forth}}==
Line 1,225 ⟶ 1,650:
Needs the FMS-SI (single inheritance) library code located here:
http://soton.mpeforth.com/flag/fms/index.html
<
include FMS-SILib.f
Line 1,236 ⟶ 1,661:
o{ o{ 1 } 2 o{ o{ 3 4 } 5 } o{ o{ o{ } } } o{ o{ o{ 6 } } } 7 8 o{ } }
list flatten
list p: \ o{ 1 2 3 4 5 6 7 8 } ok</
=={{header|Fortran}}==
<
! input : [[1], 2, [[3, 4], 5], [[[]]], [[[6]]], 7, 8, []]
! flatten : [1, 2, 3, 4, 5, 6, 7, 8 ]
Line 1,391 ⟶ 1,816:
print *, "]"
end program
</syntaxhighlight>
===Or, older style===
Fortran does not offer strings, only CHARACTER variables of some fixed size. Functions can return such types, but, must specify a fixed size. Or, mess about with run-time allocation as above. Since in principle a list is arbitrarily long, the plan here is to crush its content in place, and thereby never have to worry about long-enough work areas. This works because the transformations in mind never replace something by something longer. A subroutine can receive an arbitrary-sized CHARACTER variable, and can change it. No attempt is made to detect improper lists.
<syntaxhighlight lang="fortran">
SUBROUTINE CRUSH(LIST) !Changes LIST.
Crushes a list holding multi-level entries within [...] to a list of single-level entries. Null entries are purged.
Line 1,428 ⟶ 1,853:
CALL CRUSH(STUFF) !Can't be a constant, as it will be changed.
WRITE (6,*) " Crushed: ",STUFF !Behold!
END</
Output is
Original: [[1], 2, [[3,4], 5], [[[]]], [[[6]]], 7, 8, []]
Line 1,437 ⟶ 1,862:
=={{header|Frink}}==
<
a = [[1], 2, [[3,4], 5], [[[]]], [[[6]]], 7, 8, []]
println[flatten[a]]
</syntaxhighlight>
=={{header|FutureBasic}}==
Definitely old school.
<syntaxhighlight lang="futurebasic">
local fn FlattenList( list as Str255 ) as Str255
long i
Str255 flatStr, commaStr
flatStr = ""
for i = 1 to len$(list)
if ( instr$( 0, "[] ,", mid$( list, i, 1 ) ) === 0 )
flatStr += commaStr + mid$( list, i, 1 )
commaStr = ", "
end if
next
end fn = flatStr
window 1, @"Flatten a list", ( 0, 0, 350, 150 )
print "["; fn FlattenList( "[[1], 2, [[3,4], 5], [[[]]], [[[6]]], 7, 8 []]" ); "]"
HandleEvents</syntaxhighlight>
{{output}}
<pre>[1, 2, 3, 4, 5, 6, 7, 8]</pre>
Modern and a little outside the box.
<syntaxhighlight lang="futurebasic">
void local fn FlattenAList
CFStringRef listStr = @"[[1], 2, [[3, 4], 5], [[[]]], [[[6]]], 7, 8, []]"
CFArrayRef listArr = fn StringComponentsSeparatedByCharactersInSet( listStr, fn CharacterSetWithCharactersInString( @"\"[ ]," ) )
CFMutableArrayRef mutArr = fn MutableArrayWithArray( listArr )
MutableArrayRemoveObject( mutArr, @"" )
CFStringRef flatStr = fn ArrayComponentsJoinedByString( mutArr, @", " )
printf @"[%@]", flatStr
end fn
fn FlattenAList
HandleEvents
</syntaxhighlight>
{{output}}
<pre>[1, 2, 3, 4, 5, 6, 7, 8]</pre>
=={{header|GAP}}==
<
=={{header|GNU APL}}==
Using (monadic) enlist function ε. Sometimes called 'Super Ravel'.
<syntaxhighlight lang="apl">
⊢list←(2 3ρι6)(2 2ρ(7 8(2 2ρ9 10 11 12)13)) 'ABCD'
┏→━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃┏→━━━━┓ ┏→━━━━━━━━━┓ "ABCD"┃
┃↓1 2 3┃ ↓ 7 8┃ ┃
┃┃4 5 6┃ ┃ ┃ ┃
┃┗━━━━━┛ ┃┏→━━━━┓ 13┃ ┃
┃ ┃↓ 9 10┃ ┃ ┃
┃ ┃┃11 12┃ ┃ ┃
┃ ┃┗━━━━━┛ ┃ ┃
┃ ┗∊━━━━━━━━━┛ ┃
┗∊∊━━━━━━━━━━━━━━━━━━━━━━━━━┛
∊list
┏→━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃1 2 3 4 5 6 7 8 9 10 11 12 13 'A''B''C''D'┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
</syntaxhighlight>
=={{header|Go}}==
<
import "fmt"
Line 1,478 ⟶ 1,965:
}
return
}</
{{out}}
<pre>
Line 1,486 ⟶ 1,973:
In the code above, flatten uses an easy-to-read type switch to extract ints and return an int slice. The version below is generalized to return a flattened slice of interface{} type, which can of course refer to objects of any type, and not just int.
Also, just to show a variation in programming style, a type assertion is used rather than a type switch.
<
for _, e := range s {
if i, ok := e.([]interface{}); ok {
Line 1,495 ⟶ 1,982:
}
return
}</
=={{header|Groovy}}==
Line 1,501 ⟶ 1,988:
<code>List.flatten()</code> is a Groovy built-in that returns a flattened copy of the source list:
<
=={{header|Haskell}}==
Line 1,507 ⟶ 1,994:
In Haskell we have to interpret this structure as an algebraic data type.
<
-- [[1], 2, [[3,4], 5], [[[]]], [[[6]]], 7, 8, []]
-- implemented as multiway tree:
-- Data.Tree represents trees where nodes have values too, unlike the trees in our problem.
-- so we use a list as that value, where a node will have an empty list value,
-- and a leaf will have a one-element list value and no subtrees
list :: Tree [Int]
list =
Node
[ Node []
, Node [] [Node [] [Node [3] [], Node [4]
, Node [] [Node [] [Node []
]
flattenList
flattenList = concat . flatten
main :: IO ()
main = print $ flattenList list</syntaxhighlight>
{{Out}}
<pre>[1,2,3,4,5,6,7,8]</pre>
Alternately:
<syntaxhighlight lang="haskell">data Tree a
= Leaf a
| Node [Tree a]
flatten :: Tree a -> [a]
flatten (Leaf x) = [x]
flatten (Node xs) =
main :: IO ()
main =
(print . flatten) $
Node
, Node [Node [Leaf 3, Leaf
, Node [Node
, Node [Node [Node [Leaf 6]]]
, Leaf 7
, Leaf 8
, Node []
]
-- [1,2,3,4,5,6,7,8]</syntaxhighlight>
Yet another choice, custom data structure, efficient lazy flattening:
Line 1,557 ⟶ 2,052:
(This is unnecessary; since Haskell is lazy, the previous solution will only do just as much work as necessary for each element that is requested from the resulting list.)
<syntaxhighlight lang
= NList [NestedList a]
| Entry a
flatten :: NestedList a -> [a]
flatten nl =
where
flatten_ :: NestedList a -> [a] -> [a]
-- By passing through a list to which the results will be prepended,
-- we allow for efficient lazy evaluation
example :: NestedList Int
example =
NList
[ NList [Entry 1]
, Entry 2
, NList [NList [Entry 3, Entry 4], Entry 5]
, NList [NList [NList []]]
, NList [NList [NList [Entry 6]]]
, Entry 7
, Entry 8
, NList []
]
main :: IO ()
main = print $ flatten example
-- output [1,2,3,4,5,6,7,8]</syntaxhighlight>
=={{header|Hy}}==
<syntaxhighlight lang="clojure">(defn flatten [lst]
(sum (genexpr (if (isinstance x list)
(flatten x)
[x])
[x lst])
[]))
(print (flatten [[1] 2 [[3 4] 5] [[[]]] [[[6]]] 7 8 []]))
; [1, 2, 3, 4, 5, 6, 7, 8]</syntaxhighlight>
=={{header|Icon}} and {{header|Unicon}}==
The following procedure solves the task using a string representation of nested lists and cares not if the list is well formed or not.
<
procedure sflatten(s) # uninteresting string solution
return pretrim(trim(compress(deletec(s,'[ ]'),',') ,','),',')
end</
{{libheader|Icon Programming Library}}
The solution uses several procedures from [http://www.cs.arizona.edu/icon/library/src/procs/strings.icn strings in the IPL]
This procedure is more in the spirit of the task handling actual lists rather than representations. It uses a recursive approach using some of the built-in list manipulation functions and operators.
<
local l,x
Line 1,594 ⟶ 2,112:
else put(l,x)
return l
end</
Finally a demo routine to drive these and a helper to show how it works.
<
write(sflatten(" [[1], 2, [[3,4], 5], [[[]]], [[[6]]], 7, 8, []]"))
writelist(flatten( [[1], 2, [[3,4], 5], [[[]]], [[[6]]], 7, 8, []]))
Line 1,607 ⟶ 2,125:
write(" ]")
return
end</
=={{header|Insitux}}==
Insitux has a built-in flatten function.
<syntaxhighlight lang="insitux">
(flatten [[1] 2 [[3 4] 5] [[[]]] [[[6]]] 7 8 []])
</syntaxhighlight>
{{out}}
<pre>
[1 2 3 4 5 6 7 8]
</pre>
=={{header|Ioke}}==
<
[[1], 2, [[3,4], 5], [[[]]], [[[6]]], 7, 8, []] flatten
+> [1, 2, 3, 4, 5, 6, 7, 8]</
=={{header|Isabelle}}==
<syntaxhighlight lang="isabelle">theory Scratch
imports Main
begin
datatype 'a tree = Leaf 'a ("<_>")
| Node "'a tree list" ("⟦ _ ⟧")
text‹The datatype introduces special pretty printing:›
lemma "Leaf a = <a>" by simp
lemma "Node [] = ⟦ [] ⟧" by simp
definition "example ≡ ⟦[ ⟦[<1>]⟧, <2>, ⟦[ ⟦[<3>, <4>]⟧, <5>]⟧, ⟦[⟦[⟦[]⟧]⟧]⟧, ⟦[⟦[⟦[<6>]⟧]⟧]⟧, <7>, <8>, ⟦[]⟧ ]⟧"
lemma "example =
Node [
Node [Leaf 1],
Leaf 2,
Node [Node [Leaf 3, Leaf 4], Leaf 5],
Node [Node [ Node []]],
Node [Node [Node [Leaf 6]]],
Leaf 7,
Leaf 8,
Node []
]"
by(simp add: example_def)
fun flatten :: "'a tree ⇒ 'a list" where
"flatten (Leaf a) = [a]"
| "flatten (Node xs) = concat (map flatten xs)"
lemma "flatten example = [1, 2, 3, 4, 5, 6, 7, 8]"
by(simp add: example_def)
end</syntaxhighlight>
=={{header|J}}==
'''Solution''':
<
'''Example''':
<
]li =. (<1) ; 2; ((<3; 4); 5) ; ((<a:)) ; ((<(<6))) ; 7; 8; <a:
+---+-+-----------+----+-----+-+-+--+
Line 1,633 ⟶ 2,198:
flatten li
1 2 3 4 5 6 7 8</
'''Notes:'''
Line 1,648 ⟶ 2,213:
'''Alternative Solution:'''<br>
The previous solution can be generalized to flatten the nesting and shape for a list of arbitrary values that include arrays of any rank:
<
'''Example:'''
<
+---+-+---------------------+----+------+--+--+--+
|+-+|2|+-------+-----------+|+--+|+----+|18|19|++|
Line 1,665 ⟶ 2,230:
1 2 3 4 5 6 7 8
flatten2 li2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19</
Here, we have replaced <code><S:0</code> with <code><@,S:0</code> so our leaves are flattened before the final step where their boxes are razed.
Line 1,677 ⟶ 2,242:
Actual Workhorse code
<
import java.util.List;
Line 1,698 ⟶ 2,263:
}
}
}</
Method showing population of the test List and usage of flatten method.
<
import java.util.List;
Line 1,716 ⟶ 2,281:
return asList(a);
}
}</
{{out}}
Line 1,724 ⟶ 2,289:
;Functional version
{{works with|Java|8+}}
<
import java.util.stream.Stream;
import java.util.stream.Collectors;
Line 1,740 ⟶ 2,305:
return flattenToStream(list).collect(Collectors.toList());
}
}</
=={{header|JavaScript}}==
===ES5===
<
return list.reduce(function (acc, val) {
return acc.concat(val.constructor === Array ? flatten(val) : val);
}, []);
}</
Or, expressed in terms of the more generic '''concatMap''' function:
<
'use strict';
Line 1,770 ⟶ 2,335:
);
})();</
From fusion of ''flatten'' with ''concatMap'' we can then derive:
<syntaxhighlight lang="javascript"> // flatten :: Tree a -> [a]
function flatten(a) {
return a instanceof Array ? [].concat.apply([], a.map(flatten)) : a;
}</syntaxhighlight>
For example:
<syntaxhighlight lang="javascript">(function () {
'use strict';
// flatten :: Tree a -> [a]
function flatten(a) {
return a instanceof Array ? [].concat.apply([], a.map(flatten)) : a;
}
return flatten(
[[1], 2, [[3, 4], 5], [[[]]], [[[6]]], 7, 8, []]
);
})();</syntaxhighlight>
{{Out}}
Line 1,777 ⟶ 2,366:
===ES6===
====Built-in====
<syntaxhighlight lang="javascript">// flatten :: NestedList a -> [a]
const flatten = nest =>
nest.flat(Infinity);</syntaxhighlight>
====Recursive====
<syntaxhighlight lang="javascript">// flatten :: NestedList a -> [a]
const flatten = t => {
const go = x =>
Array.isArray(x) ? (
x.flatMap(go)
) : x;
return go(t);
};</syntaxhighlight>
====Iterative====
<syntaxhighlight lang="javascript">function flatten(list) {
for (let i = 0; i < list.length; i++) {
while (true) {
if (Array.isArray(list[i])) {
list.splice(i, 1, ...list[i]);
} else {
break;
}
}
}
return list;
}</syntaxhighlight>
Or alternatively:
<syntaxhighlight lang="javascript">// flatten :: Nested List a -> a
const flatten = t => {
let xs = t;
while (xs.some(Array.isArray)) {
xs = [].concat(...xs);
}
return xs;
};</syntaxhighlight>
Result is always:
Line 1,785 ⟶ 2,413:
=={{header|Joy}}==
<syntaxhighlight lang="joy">
"seqlib" libload.
Line 1,791 ⟶ 2,419:
(* output: [1 2 3 4 5 6 7 8] *)
</syntaxhighlight>
=={{header|jq}}==
Recent (1.4+) versions of jq include the following flatten filter:<
reduce .[] as $i
([];
if $i | type == "array" then . + ($i | flatten)
else . + [$i]
end);</
[[1], 2, [[3,4], 5], [[[]]], [[[6]]], 7, 8, []] | flatten
[1,2,3,4,5,6,7,8]</
=={{header|Jsish}}==
From Javascript entry, with change to test for ''typeof'' equal ''"array"''.
<syntaxhighlight lang="javascript">/* Flatten list, in Jsish */
function flatten(list) {
return list.reduce(function (acc, val) {
return acc.concat(typeof val === "array" ? flatten(val) : val);
}, []);
}
if (Interp.conf('unitTest')) {
; flatten([[1], 2, [[3, 4], 5], [[[]]], [[[6]]], 7, 8, []]);
}
/*
=!EXPECTSTART!=
flatten([[1], 2, [[3, 4], 5], [[[]]], [[[6]]], 7, 8, []]) ==> [ 1, 2, 3, 4, 5, 6, 7, 8 ]
=!EXPECTEND!=
*/</syntaxhighlight>
{{out}}
<pre>prompt$ jsish --U flatten.jsi
flatten([[1], 2, [[3, 4], 5], [[[]]], [[[6]]], 7, 8, []]) ==> [ 1, 2, 3, 4, 5, 6, 7, 8 ]</pre>
=={{header|Julia}}==
(Note that Julia versions prior to 0.5 automatically flattened nested arrays.)
The following version of flatten makes use of the higher order function ''mapreduce''.
<syntaxhighlight lang="julia">isflat(x) = isempty(x) || first(x) === x
function flat_mapreduce(arr)
mapreduce(vcat, arr, init=[]) do x
isflat(x) ? x : flat(x)
end
end</syntaxhighlight>
An iterative recursive version that uses less memory but is slower:
<syntaxhighlight lang="julia">function flat_recursion(arr)
res = []
function grep(v)
for x in v
if x isa Array
grep(x)
else
push!(res, x)
end
end
end
grep(arr)
res
end</syntaxhighlight>
Using the Iterators library from the Julia base:
<syntaxhighlight lang="julia">function flat_iterators(arr)
while any(a -> a isa Array, arr)
arr = collect(Iterators.flatten(arr))
end
arr
end</syntaxhighlight>
Benchmarking these three functions using the BenchmarkTools package yields the following results:
<syntaxhighlight lang="julia">using BenchmarkTools
arr = [[1], 2, [[3, 4], 5], [[[]]], [[[6]]], 7, 8, []]
@show flat_mapreduce(arr)
@show flat_recursion(arr)
@show flat_iterators(arr)
@btime flat_mapreduce($arr)
@btime flat_recursion($arr)
@btime flat_iterators($arr)</syntaxhighlight>{{out}}
<pre>
flat_iterators(arr) = [1, 2, 3, 4, 5, 6, 7, 8]
14.163 μs (131 allocations: 4.27 KiB)
500.824 ns (4 allocations: 176 bytes)
28.223 μs (133 allocations: 4.33 KiB)
</pre>
Line 1,839 ⟶ 2,513:
So to flatten a list of arbitrary depth, you can join-over-over, or reduce a list with a function that reduces a list with a join function:
<
=={{header|Kotlin}}==
<syntaxhighlight lang="scala">// version 1.0.6
@Suppress("UNCHECKED_CAST")
fun flattenList(nestList: List<Any>, flatList: MutableList<Int>) {
for (e in nestList)
if (e is Int)
flatList.add(e)
else
// using unchecked cast here as can't check for instance of 'erased' generic type
flattenList(e as List<Any>, flatList)
}
fun main(args: Array<String>) {
val nestList : List<Any> = listOf(
listOf(1),
2,
listOf(listOf(3, 4), 5),
listOf(listOf(listOf<Int>())),
listOf(listOf(listOf(6))),
7,
8,
listOf<Int>()
)
println("Nested : " + nestList)
val flatList = mutableListOf<Int>()
flattenList(nestList, flatList)
println("Flattened : " + flatList)
}</syntaxhighlight>
Or, using a more functional approach:
<syntaxhighlight lang="scala">
fun flatten(list: List<*>): List<*> {
fun flattenElement(elem: Any?): Iterable<*> {
return if (elem is List<*>)
if (elem.isEmpty()) elem
else flattenElement(elem.first()) + flattenElement(elem.drop(1))
else listOf(elem)
}
return list.flatMap { elem -> flattenElement(elem) }
}</syntaxhighlight>
{{out}}
<pre>
Nested : [[1], 2, [[3, 4], 5], [[[]]], [[[6]]], 7, 8, []]
Flattened : [1, 2, 3, 4, 5, 6, 7, 8]
</pre>
=={{header|Lambdatalk}}==
Lambdatalk doesn't have a builtin primitive flattening a multidimensionnal array.
<syntaxhighlight lang="scheme">
1) Let's create this function
{def A.flatten
{def A.flatten.r
{lambda {:a}
{if {A.empty? :a}
then
else {let { {:b {A.first :a}}
} {if {A.array? :b}
then {A.flatten.r :b}
else :b} }
{A.flatten.r {A.rest :a}} }}}
{lambda {:a}
{A.new {A.flatten.r :a}}}}
-> A.flatten
and test it
{def list
{A.new
{A.new 1}
2
{A.new {A.new 3 4} 5}
{A.new {A.new {A.new }}}
{A.new {A.new {A.new 6}}}
7
8
{A.new}
}}
-> [[1], 2, [[3, 4], 5], [[[]]], [[[6]]], 7, 8, []]
{A.flatten {list}}
-> [1,2,3,4,5,6,7,8]
</syntaxhighlight>
=={{header|Lasso}}==
Lasso Delve is a Lasso utility method explicitly for handling embedded arrays. With one array which contain other arrays, delve allows you to treat one array as a single series of elements, thus enabling easy access to an entire tree of values. [http://www.lassosoft.com/lassoDocs/languageReference/obj/delve www.lassosoft.com/lassoDocs/languageReference/obj/delve Lasso reference on Delve]
<
#original
'<br />'
(with item in delve(#original)
select #item) -> asstaticarray</
<pre>array(array(1), 2, array(array(3, 4), 5), array(array(array())), array(array(array(6))), 7, 8, array())
staticarray(1, 2, 3, 4, 5, 6, 7, 8)</pre>
=={{header|LFE}}==
<
> (: lists flatten '((1) 2 ((3 4) 5) ((())) (((6))) 7 8 ()))
(1 2 3 4 5 6 7 8)
</syntaxhighlight>
=={{header|Logo}}==
<syntaxhighlight lang="logo">to flatten :l
if not list? :l [output :l]
if empty? :l [output []]
output sentence flatten first :l flatten butfirst :l
end
; using a template iterator (map combining results into a sentence)
to flatten :l
output map.se [ifelse or not list? ? empty? ? [?] [flatten ?]] :l
end
make "a [[1] 2 [[3 4] 5] [[[]]] [[[6]]] 7 8 []]
show flatten :a</syntaxhighlight>
=={{header|Logtalk}}==
<
flatten(List, [], Flatted).
Line 1,873 ⟶ 2,649:
flatten(Tail, List, Aux),
flatten(Head, Aux, Flatted).
flatten(Head, Tail, [Head| Tail]).</
=={{header|Lua}}==
<
if type(list) ~= "table" then return {list} end
local flat_list = {}
Line 1,890 ⟶ 2,666:
test_list = {{1}, 2, {{3,4}, 5}, {{{}}}, {{{6}}}, 7, 8, {}}
print(table.concat(flatten(test_list), ","))</
=={{header|Maple}}==
Line 1,912 ⟶ 2,672:
This can be accomplished using the <code>Flatten</code> command from the <code>ListTools</code>, or with a custom recursive procedure.
<syntaxhighlight lang="maple">
L := [[1], 2, [[3,4], 5], [[[]]], [[[6]]], 7, 8, []]:
Line 1,918 ⟶ 2,678:
Flatten(L);
</syntaxhighlight>
{{out}}
<pre>
Line 1,924 ⟶ 2,684:
</pre>
<syntaxhighlight lang="maple">
flatten := proc(x)
`if`(type(x,'list'),seq(procname(i),i = x),x);
Line 1,932 ⟶ 2,692:
[flatten(L)];
</syntaxhighlight>
{{out}}
<pre>
Line 1,939 ⟶ 2,699:
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<
=={{header|Maxima}}==
<
/* [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] */</
=={{header|Mercury}}==
As with Haskell we need to use an algebraic data type.
<
:- interface.
Line 1,981 ⟶ 2,741:
:- end_module flatten_a_list.
</syntaxhighlight>
{{out}}
<pre>
[1, 2, 3, 4, 5, 6, 7, 8]
</pre>
=={{header|min}}==
{{works with|min|0.37.0}}
<syntaxhighlight lang="min">(
(dup 'quotation? any?) 'flatten while
) ^deep-flatten
((1) 2 ((3 4) 5) ((())) (((6))) 7 8 ()) deep-flatten puts!</syntaxhighlight>
{{out}}
<pre>(1 2 3 4 5 6 7 8)</pre>
=={{header|Mirah}}==
<
import java.util.List
import java.util.Collection
Line 2,011 ⟶ 2,781:
source = [[1], 2, [[3, 4], 5], [[ArrayList.new]], [[[6]]], 7, 8, ArrayList.new]
puts flatten(source)</
=={{header|NewLISP}}==
<
(1 2 3 4 5 6 7 8)
</syntaxhighlight>
=={{header|NGS}}==
Line 2,023 ⟶ 2,793:
NGS defines '''flatten''' as a shallow flatten, hence using '''flatten_r''' here.
<
collector {
local kern
Line 2,031 ⟶ 2,801:
}
echo(flatten_r([[1], 2, [[3, 4], 5], [[[]]], [[[6]]], 7, 8, []]))</
{{out}}
Line 2,037 ⟶ 2,807:
=={{header|Nim}}==
Nim is statically-typed, so we need to use an object variant
<syntaxhighlight lang="nim">type
case isLeaf: bool
of true:
of false: list: seq[TreeList[T]]
proc L[T](list: varargs[TreeList[T]]): TreeList[T] =
for x in list:
proc N[T](data: T): TreeList[T] =
TreeList[T](isLeaf: true, data: data)
proc flatten[T](n: TreeList[T]): seq[T] =
if n.isLeaf: result = @[n.data]
else:
for x in n.list:
result.add flatten x
var x = L(L(N 1), N 2, L(L(N 3, N 4), N 5), L(L(L[int]())), L(L(L(N 6))), N 7, N 8, L[int]())
echo flatten(x)</syntaxhighlight>
{{out}}
<pre>
=={{header|Objective-C}}==
{{works with|Cocoa}}
<
@interface NSArray (FlattenExt)
Line 2,116 ⟶ 2,873:
return 0;
}</
=={{header|OCaml}}==
<
val flatten : 'a list list -> 'a list = <fun>
Line 2,128 ⟶ 2,885:
# (* use another data which can be accepted by the type system *)
flatten [[1]; [2; 3; 4]; []; [5; 6]; [7]; [8]] ;;
- : int list = [1; 2; 3; 4; 5; 6; 7; 8]</
Since OCaml is statically typed, it is not possible to have a value that could be both a list and a non-list. Instead, we can use an algebraic datatype:
<
type 'a tree = Leaf of 'a | Node of 'a tree list
Line 2,141 ⟶ 2,898:
# flatten (Node [Node [Leaf 1]; Leaf 2; Node [Node [Leaf 3; Leaf 4]; Leaf 5]; Node [Node [Node []]]; Node [Node [Node [Leaf 6]]]; Leaf 7; Leaf 8; Node []]) ;;
- : int list = [1; 2; 3; 4; 5; 6; 7; 8]</
=={{header|Oforth}}==
<
{{out}}
Line 2,152 ⟶ 2,909:
</pre>
=={{header|
<syntaxhighlight lang="scheme">
(define (flatten x)
(cond
((null? x)
((not (pair? x))
(append (flatten (car x))
(flatten (cdr x))))))
(print
(flatten '((1) 2 ((3 4) 5) ((())) (((6))) 7 8 ())))
</syntaxhighlight>
{{Out}}
<pre>
(1 2 3 4 5 6 7 8)
</pre>
=={{header|ooRexx}}==
<syntaxhighlight lang="oorexx">
sub1 = .array~of(1)
sub2 = .array~of(3, 4)
Line 2,202 ⟶ 2,967:
else accumulator~append(item)
end
</syntaxhighlight>
=={{header|Oz}}==
Oz has a standard library function "Flatten":
<syntaxhighlight lang="oz">{Show {Flatten [[1] 2 [[3 4] 5] [[nil]] [[[6]]] 7 8 nil]}}</syntaxhighlight>
A simple, non-optimized implementation could look like this:
<syntaxhighlight lang="oz">fun {Flatten2 Xs}
case Xs of nil then nil
[] X|Xr then
{Append {Flatten2 X} {Flatten2 Xr}}
else [Xs]
end
end
</syntaxhighlight>
=={{header|PARI/GP}}==
<
my(u=[]);
for(i=1,#v,
Line 2,211 ⟶ 2,989:
);
u
};</
=={{header|Perl}}==
<
map { ref eq 'ARRAY' ? flatten(@$_) : $_ } @_
}
my @lst = ([1], 2, [[3,4], 5], [[[]]], [[[6]]], 7, 8, []);
print flatten(@lst), "\n";</
=={{header|Phix}}==
standard builtin
<
{{out}}
<pre>
{1,2,3,4,5,6,7,8}
</pre>
=={{header|Phixmonti}}==
<syntaxhighlight lang="phixmonti">1 2 3 10 20 30 3 tolist 4 5 6 3 tolist 2 tolist 1000 "Hello" 6 tolist
dup print nl flatten print</syntaxhighlight>
With syntactic sugar
<syntaxhighlight lang="phixmonti">include ..\Utilitys.pmt
( 1 2 3 ( ( 10 20 30 ) ( 4 5 6 ) ) 1000 "Hola" )
dup ? flatten ?</syntaxhighlight>
{{out}}
<pre>
[1, 2, 3, [[10, 20, 30], [4, 5, 6]], 1000, "Hello"]
[1, 2, 3, 10, 20, 30, 4, 5, 6, 1000, "Hello"]
</pre>
=={{header|PHP}}==
{{works with|PHP|4.x only, not 5.x}}
<
It won't work on PHP 5 due to the change in behavior of array_merge(). */
while (array_filter($lst, 'is_array'))
$lst = call_user_func_array('array_merge', $lst);</
Explanation: while <code>$lst</code> has any elements which are themselves arrays (i.e. <code>$lst</code> is not flat), we merge the elements all together (in PHP 4, <code>array_merge()</code> treated non-array arguments as if they were 1-element arrays; PHP 5 <code>array_merge()</code> no longer allows non-array arguments.), thus flattening the top level of any embedded arrays. Repeat this process until the array is flat.
===Recursive===
<
function flatten($ary) {
$result = array();
Line 2,261 ⟶ 3,049:
$lst = array(array(1), 2, array(array(3, 4), 5), array(array(array())), array(array(array(6))), 7, 8, array());
var_dump(flatten($lst));
?></
Alternatively:{{works with|PHP|5.3+}}
<
function flatten($ary) {
$result = array();
Line 2,274 ⟶ 3,062:
$lst = array(array(1), 2, array(array(3, 4), 5), array(array(array())), array(array(array(6))), 7, 8, array());
var_dump(flatten($lst));
?></
<
function flatten_helper($x, $k, $obj) {
$obj->flattened[] = $x;
Line 2,289 ⟶ 3,077:
$lst = array(array(1), 2, array(array(3, 4), 5), array(array(array())), array(array(array(6))), 7, 8, array());
var_dump(flatten($lst));
?></
Using the standard library (warning: objects will also be flattened by this method):
<
$lst = array(array(1), 2, array(array(3, 4), 5), array(array(array())), array(array(array(6))), 7, 8, array());
$result = iterator_to_array(new RecursiveIteratorIterator(new RecursiveArrayIterator($lst)), false);
var_dump($result);
?></
===Non-recursive===
Function flat is iterative and flattens the array in-place.
<
function flat(&$ary) { // argument must be by reference or array will just be copied
for ($i = 0; $i < count($ary); $i++) {
Line 2,314 ⟶ 3,102:
flat($lst);
var_dump($lst);
?></
=={{header|PicoLisp}}==
<
(make # Build a list
(recur (X) # recursively over 'X'
(if (atom X)
(link X) # Put atoms into the result
(mapc recurse X) ) ) ) ) # or recurse on sub-lists</
or a more succint way using [http://www.software-lab.de/doc/refF.html#fish fish]:
<
(fish atom X) )</
=={{header|Pike}}==
There's a built-in function called <code>Array.flatten()</code> which does this, but here's a custom function:
<
array r = ({ });
Line 2,340 ⟶ 3,128:
return r;
}</
=={{header|PL/I}}==
The Translate(text,that,this) intrinsic function returns ''text'' with any character in ''text'' that is found in ''this'' (say the third) replaced by the corresponding third character in ''that''. Suppose the availability of a function Replace(text,that,this) which returns ''text'' with all occurrences of ''this'' (a single text, possibly many characters) replaced by ''that'', possibly zero characters. The Translate function does not change the length of its string, simply translate its characters in place.
<syntaxhighlight lang="pl/i">
list = translate (list, ' ', '[]' ); /*Produces " 1 , 2, 3,4 , 5 , , 6 , 7, 8, " */
list = Replace(list,'',' '); /*Converts spaces to nothing. Same parameter order as Translate.*/
Line 2,351 ⟶ 3,139:
end; /*And search afresh, in case of multiple commas in a row.*/
list = '[' || list || ']'; /*Repackage the list.*/
</syntaxhighlight>
This is distinctly crude. A user-written Replace function is confronted by the requirement to specify a maximum size for its returned result, for instance <code>Replace:Procedure(text,that,this) Returns(Character 200 Varying);</code> which is troublesome for general use. The intrinsic function Translate has no such restriction.
Line 2,358 ⟶ 3,146:
=={{header|PostScript}}==
{{libheader|initlib}}
<
/flatten {
/.f {{type /arraytype eq} {{.f} map aload pop} ift}.
[exch .f]
}.
</syntaxhighlight>
<syntaxhighlight lang="text">
[[1] 2 [[3 4] 5] [[[]]] [[[6]]] 7 8 []] flatten
</syntaxhighlight>
=={{header|PowerShell}}==
<syntaxhighlight lang="powershell">
function flatten($a) {
if($a.Count -gt 1) {
Line 2,377 ⟶ 3,165:
$a = @(@(1), 2, @(@(3,4), 5), @(@(@())), @(@(@(6))), 7, 8, @())
"$(flatten $a)"
</syntaxhighlight>
<b>Output:</b>
<pre>
Line 2,384 ⟶ 3,172:
=={{header|Prolog}}==
<syntaxhighlight lang="prolog">
flatten(List, FlatList) :-
flatten(List, [], FlatList).
Line 2,396 ⟶ 3,184:
flatten(NonList, T, [NonList|T]).
</syntaxhighlight>
=={{header|Python}}==
===Recursive===
<syntaxhighlight lang="python">>>> def flatten(lst):
return sum( ([x] if not isinstance(x, list) else flatten(x)
for x in lst), [] )
Line 2,465 ⟶ 3,194:
>>> lst = [[1], 2, [[3,4], 5], [[[]]], [[[6]]], 7, 8, []]
>>> flatten(lst)
[1, 2, 3, 4, 5, 6, 7, 8]</
===Recursive, generative and working with any type of iterable object===
<syntaxhighlight lang="python">>>> def flatten(itr):
>>> for x in itr:
>>> try:
>>> yield from flatten(x)
>>> except:
>>> yield x
>>> lst = [[1], 2, [[3,4], 5], [[[]]], [[[6]]], 7, 8, []]
>>> list(flatten(lst))
[1, 2, 3, 4, 5, 6, 7, 8]
>>> tuple(flatten(lst))
(1, 2, 3, 4, 5, 6, 7, 8)
>>>for i in flatten(lst):
>>> print(i)
1
2
3
4
5
6
7
8</syntaxhighlight>
===Non-recursive===
Function flat is iterative and flattens the list in-place. It follows the Python idiom of returning None when acting in-place:
<
i=0
while i<len(lst):
Line 2,483 ⟶ 3,238:
>>> flat(lst)
>>> lst
[1, 2, 3, 4, 5, 6, 7, 8]</
===Generative===
Line 2,491 ⟶ 3,246:
In this case, the generator is converted back to a list before printing.
<
for x in lst:
if isinstance(x, list):
Line 2,502 ⟶ 3,257:
>>> lst = [[1], 2, [[3,4], 5], [[[]]], [[[6]]], 7, 8, []]
>>> print list(flatten(lst))
[1, 2, 3, 4, 5, 6, 7, 8]</
===Functional Recursive===
And, as [[Rosetta_Code|the idea of Rosetta Code]] is to demonstrate how languages are '''similar''' as well as different, and to thus to 'aid a person with a grounding in one approach to a problem in learning another', here it is in terms of '''concatMap''', which can be defined in any language, including mathematics, and which can be variously expressed in Python. (The fastest Python implementation of the '''concat''' component of the (concat . map) composition seems to be in terms of ''itertools.chain'').
{{Works with|Python|3.7}}
<syntaxhighlight lang="python">'''Flatten a nested list'''
from itertools import (chain)
# ----------------------- FLATTEN ------------------------
# flatten :: NestedList a -> [a]
def flatten(x):
'''A list of atomic values resulting from fully
flattening an arbitrarily nested list.
'''
return concatMap(flatten)(x) if (
isinstance(x, list)
) else [x]
# ------------------------- TEST -------------------------
def main():
'''Test: flatten an arbitrarily nested list.
'''
print(
fTable(__doc__ + ':')(showList)(showList)(
flatten
)([
[[[]]],
[[1, 2, 3]],
[[1], [[2]], [[[3, 4]]]],
[[1], 2, [[3, 4], 5], [[[]]], [[[6]]], 7, 8, []]
])
)
# ----------------------- GENERIC ------------------------
# compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
def compose(g):
'''Right to left function composition.'''
return lambda f: lambda x: g(f(x))
# concatMap :: (a -> [b]) -> [a] -> [b]
def concatMap(f):
'''A concatenated list over which a function has been mapped.
The list monad can be derived by using a function f which
wraps its output in a list,
(using an empty list to represent computational failure).
'''
def go(xs):
return chain.from_iterable(map(f, xs))
return go
# fTable :: String -> (a -> String) ->
# (b -> String) ->
# (a -> b) -> [a] -> String
def fTable(s):
'''Heading -> x display function ->
fx display function ->
f -> value list -> tabular string.'''
def go(xShow, fxShow, f, xs):
w = max(map(compose(len)(xShow), xs))
return s + '\n' + '\n'.join([
xShow(x).rjust(w, ' ') + (' -> ') + fxShow(f(x))
for x in xs
])
return lambda xShow: lambda fxShow: lambda f: lambda xs: go(
xShow, fxShow, f, xs
)
# showList :: [a] -> String
def showList(xs):
'''Stringification of a list.'''
return '[' + ','.join(str(x) for x in xs) + ']'
if __name__ == '__main__':
main()</syntaxhighlight>
{{Out}}
<pre>Flatten a nested list:
[[[]]] -> []
[[1, 2, 3]] -> [1,2,3]
[[1],[[2]],[[[3, 4]]]] -> [1,2,3,4]
[[1],2,[[3, 4], 5],[[[]]],[[[6]]],7,8,[]] -> [1,2,3,4,5,6,7,8]</pre>
===Functional Non-recursive===
And, in contexts where it may be desirable to avoid not just recursion, but also:
# mutation of the original list, and
# dependence on error-events for evaluation control,
we can again use the universal '''concat . map''' composition (see the second recursive example above) by embedding it in a fold / reduction, and using it with a pure, but iteratively-implemented, '''until''' function.
( Note that the generic functions in the following example are ''curried'', enabling not only more flexible composition, but also some simplifying reductions – here eliminating the need for two uses of Python's ''lambda'' keyword ):
{{Works with|Python|3.7}}
<syntaxhighlight lang="python">'''Flatten a list'''
from functools import (reduce)
from itertools import (chain)
def flatten(xs):
'''A flat list of atomic values derived
from a nested list.
'''
return reduce(
lambda a, x: a + list(until(every(notList))(
concatMap(pureList)
)([x])),
xs, []
)
# TEST ----------------------------------------------------
def main():
'''From nested list to flattened list'''
print(main.__doc__ + ':\n\n')
xs = [[1], 2, [[3, 4], 5], [[[]]], [[[6]]], 7, 8, []]
print(
repr(xs) + ' -> ' + repr(flatten(xs))
)
# GENERIC -------------------------------------------------
# concatMap :: (a -> [b]) -> [a] -> [b]
def concatMap(f):
'''A concatenated list over which a function has been mapped.
The list monad can be derived by using a function f which
wraps its output in a list,
(using an empty list to represent computational failure).
'''
return lambda xs: list(
chain.from_iterable(map(f, xs))
)
# every :: (a -> Bool) -> [a] -> Bool
def every(p):
'''True if p(x) holds for every x in xs'''
def go(p, xs):
return all(map(p, xs))
return lambda xs: go(p, xs)
# notList :: a -> Bool
def notList(x):
'''True if the value x is not a list.'''
return not isinstance(x, list)
# pureList :: a -> [b]
def pureList(x):
'''x if x is a list, othewise [x]'''
return x if isinstance(x, list) else [x]
# until :: (a -> Bool) -> (a -> a) -> a -> a
def until(p):
'''The result of repeatedly applying f until p holds.
The initial seed value is x.'''
def go(f, x):
v = x
while not p(v):
v = f(v)
return v
return lambda f: lambda x: go(f, x)
if __name__ == '__main__':
main()</syntaxhighlight>
{{Out}}
<pre>From nested list to flattened list:
[[1], 2, [[3, 4], 5], [[[]]], [[[6]]], 7, 8, []] -> [1, 2, 3, 4, 5, 6, 7, 8]</pre>
=={{header|Q}}==
{{trans|K}}
We repeatedly apply <tt>raze</tt> until the return value converges to a fixed value.
<syntaxhighlight lang="q">(raze/) ((1); 2; ((3;4); 5); ((())); (((6))); 7; 8; ())</syntaxhighlight>
=={{header|Quackery}}==
<syntaxhighlight lang="quackery">forward is flatten
[ [] swap
witheach
[ dup nest?
if flatten
join ] ] resolves flatten ( [ --> [ )</syntaxhighlight>
'''Output:'''
<syntaxhighlight lang="quackery">/O> ' [ [ 1 ] 2 [ [ 3 4 ] 5 ] [ [ [ ] ] ] [ [ [ 6 ] ] ] 7 8 [ ] ] flatten
...
Stack: [ 1 2 3 4 5 6 7 8 ]</syntaxhighlight>
=={{header|R}}==
<syntaxhighlight lang="r">x <- list(list(1), 2, list(list(3, 4), 5), list(list(list())), list(list(list(6))), 7, 8, list())
unlist(x)</syntaxhighlight>
=={{header|Racket}}==
Racket has a built-in flatten function:
<syntaxhighlight lang="racket">
#lang racket
(flatten '(1 (2 (3 4 5) (6 7)) 8 9))
</syntaxhighlight>
{{out}}
<pre>
Line 2,522 ⟶ 3,482:
or, writing it explicitly with the same result:
<syntaxhighlight lang="racket">
#lang racket
(define (flatten l)
Line 2,529 ⟶ 3,489:
[else (append (flatten (first l)) (flatten (rest l)))]))
(flatten '(1 (2 (3 4 5) (6 7)) 8 9))
</syntaxhighlight>
=={{header|Raku}}==
(formerly Perl 6)
{{works with|Rakudo Star|2018.03}}
<syntaxhighlight lang="raku" line>my @l = [[1], 2, [[3,4], 5], [[[]]], [[[6]]], 7, 8, []];
say .perl given gather @l.deepmap(*.take); # lazy recursive version
# Another way to do it is with a recursive function (here actually a Block calling itself with the &?BLOCK dynamic variable):
say { |(@$_ > 1 ?? map(&?BLOCK, @$_) !! $_) }(@l)</syntaxhighlight>
=={{header|REBOL}}==
<
flatten: func [
"Flatten the block in place."
Line 2,542 ⟶ 3,514:
head block
]
</syntaxhighlight>
Sample: <pre>
Line 2,549 ⟶ 3,521:
</pre>
=={{header|
<syntaxhighlight lang="red">
flatten: function [
"Flatten the block"
block [any-block!]
][
load form block
]
red>> flatten [[1] 2 [[3 4] 5] [[[]]] [[[6]]] 7 8 []]
== [1 2 3 4 5 6 7 8]
;flatten a list to a string
>> blk: [1 2 ["test"] "a" [["bb"]] 3 4 [[[99]]]]
>> form blk
== "1 2 test a bb 3 4 99"</syntaxhighlight>
=={{header|Refal}}==
<syntaxhighlight lang="refal">$ENTRY Go {
, ((1) 2 ((3 4) 5) ((())) (((6))) 7 8 ()): e.List
= <Prout e.List ' -> ' <Flatten e.List>>
};
Flatten {
= ;
s.I e.X = s.I <Flatten e.X>;
(e.X) e.Y = <Flatten e.X> <Flatten e.Y>;
};</syntaxhighlight>
{{out}}
<pre>((1 )2 ((3 4 )5 )((()))(((6 )))7 8 ()) -> 1 2 3 4 5 6 7 8</pre>
=={{header|REXX}}==
{{trans|PL/I}}
<syntaxhighlight lang="rexx">/*REXX program (translated from PL/I) flattens a list (the data need not be numeric).*/
list= '[[1], 2, [[3,4], 5], [[[]]], [[[6]]], 7, 8, []]' /*the list to be flattened. */
say list /*display the original list. */
c= ',' /*define a literal (1 comma). */
cc= ',,' /* " " " (2 commas).*/
list= translate(list, , "[]") /*translate brackets to blanks.*/
list= space(list, 0) /*Converts spaces to nulls. */
do while index(list, cc) > 0 /*any double commas ? */
list= changestr(cc, list, c) /*convert ,, to single comma.*/
end /*while*/
list= strip(list, 'T', c) /*strip the last trailing comma*/
list = '['list"]" /*repackage the list. */
say list /*display the flattened list. */</syntaxhighlight>
{{out|output|:}}
<pre>
[[1], 2, [[3,4], 5], [[[]]], [[[6]]], 7, 8, []]
[1,2,3,4,5,6,7,8]
</pre>
=={{header|Ring}}==
<
for n=1 to len(
if ascii(
ok
next
see
</syntaxhighlight>
<pre>
"1, 2, 3, 4, 5, 6, 7, 8"
</pre>
=={{header|RPL}}==
Soberly recursive.
{{works with|Halcyon Calc|4.2.7}}
≪ '''IF''' DUP SIZE '''THEN'''
{ } 1 LAST '''FOR''' j
OVER j GET
'''IF''' DUP TYPE 5 == '''THEN FLATL END'''
+ '''NEXT'''
SWAP DROP '''END'''
≫ ‘'''FLATL'''’ STO
{{1} 2 {{3 4} 5} {{{}}} {{{6}}} 7 8 {}} '''FLATL'''
{{out}}
<pre>
1: { 1 2 3 4 5 6 7 8 }
</pre>
=={{header|Ruby}}==
<code>flatten</code> is a built-in method of Arrays
<
p flat # => [1, 2, 3, 4, 5, 6, 7, 8]</
The <code>flatten</code> method takes an optional argument, which dedicates the amount of levels to be flattened.
<
# => [1, 2, [3, 4], 5, [[]], [[6]], 7, 8]
</syntaxhighlight>
=={{header|
First we have to create a type that supports arbitrary nesting:
<syntaxhighlight lang="rust">use std::{vec, mem, iter};
enum List<T> {
Node(Vec<List<T>>),
Leaf(T),
}
impl<T> IntoIterator for List<T> {
type Item = List<T>;
type IntoIter = ListIter<T>;
fn into_iter(self) -> Self::IntoIter {
match self {
List::Node(vec) => ListIter::NodeIter(vec.into_iter()),
leaf @ List::Leaf(_) => ListIter::LeafIter(iter::once(leaf)),
}
}
}
enum ListIter<T> {
NodeIter(vec::IntoIter<List<T>>),
LeafIter(iter::Once<List<T>>),
}
impl<T> ListIter<T> {
fn flatten(self) -> Flatten<T> {
Flatten {
stack: Vec::new(),
curr: self,
}
}
}
impl<T> Iterator for ListIter<T> {
type Item = List<T>;
fn next(&mut self) -> Option<Self::Item> {
match *self {
ListIter::NodeIter(ref mut v_iter) => v_iter.next(),
ListIter::LeafIter(ref mut o_iter) => o_iter.next(),
}
}
}
struct Flatten<T> {
stack: Vec<ListIter<T>>,
curr: ListIter<T>,
}
// Flatten code is a little messy since we are shoehorning recursion into an Iterator
impl<T> Iterator for Flatten<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
loop {
match self.curr.next() {
Some(list) => {
match list {
node @ List::Node(_) => {
self.stack.push(node.into_iter());
let len = self.stack.len();
mem::swap(&mut self.stack[len - 1], &mut self.curr);
}
List::Leaf(item) => return Some(item),
}
}
None => {
if let Some(next) = self.stack.pop() {
self.curr = next;
} else {
return None;
}
}
}
}
}
}
use List::*;
fn main() {
let list = Node(vec![Node(vec![Leaf(1)]),
Leaf(2),
Node(vec![Node(vec![Leaf(3), Leaf(4)]), Leaf(5)]),
Node(vec![Node(vec![Node(vec![])])]),
Node(vec![Node(vec![Node(vec![Leaf(6)])])]),
Leaf(7),
Leaf(8),
Node(vec![])]);
for elem in list.into_iter().flatten() {
print!("{} ", elem);
}
println!();
}</syntaxhighlight>
{{output}}
<pre>1 2 3 4 5 6 7 8
</pre>
=={{header|S-lang}}==
<
define flatten (list) {
Line 2,639 ⟶ 3,733:
}
return retval;
}</
Sample:
Line 2,660 ⟶ 3,754:
=={{header|Scala}}==
<
case Nil => Nil
case (head: List[_]) :: tail => flatList(head) ::: flatList(tail)
case head :: tail => head :: flatList(tail)
}</
Sample:
Line 2,677 ⟶ 3,771:
=={{header|Scheme}}==
<
(cond ((null? x) '())
((not (pair? x)) (list x))
Line 2,684 ⟶ 3,778:
> (flatten '((1) 2 ((3 4) 5) ((())) (((6))) 7 8 ()))
(1 2 3 4 5 6 7 8)</
=={{header|Shen}}==
<syntaxhighlight lang="shen">
(define flatten
[] -> []
[X|Y] -> (append (flatten X) (flatten Y))
X -> [X])
(flatten [[1] 2 [[3 4] 5] [[[]]] [[[6]]] 7 8 []])
</syntaxhighlight>
{{out}}
<pre>
[1 2 3 4 5 6 7 8]
</pre>
=={{header|Sidef}}==
<
var flat = []
a.each { |item|
flat += (item.
}
return flat
}
var arr = [[1], 2, [[3,4], 5], [[[]]], [[[6]]], 7, 8, []]
say flatten(arr)
say arr.flatten
=={{header|Slate}}==
<
[
[| :out | s flattenOn: out] writingAs: s
Line 2,711 ⟶ 3,819:
ifTrue: [value flattenOn: w]
ifFalse: [w nextPut: value]].
].</
=={{header|Smalltalk}}==
{{works with|GNU Smalltalk}}
<
flatten [ |f|
f := OrderedCollection new.
Line 2,737 ⟶ 3,845:
{{{}}} . {{{6}}} . 7 . 8 . {} }.
(list flatten) printNl.</
Here is a non-OOP (but functional) version, which uses a block-closure as function (showing higher order features of Smalltalk):
<
flatDo :=
[:element :action |
Line 2,759 ⟶ 3,867:
flatDo
value:collection
value:[:el | newColl add: el]</
of course, many Smalltalk libraries already provide such functionality.
{{works with|Smalltalk/X}} {{works with|Pharo}}
<
=={{header|Standard ML}}==
In Standard ML, list must be homogeneous, but nested lists can be implemented as a tree-like data structure using a <code>datatype</code> statement:
<
L of 'a (* leaf *)
| N of 'a nestedList list (* node *)
</syntaxhighlight>
Flattening of this structure is similar to flatten trees:
<
| flatten (N xs) = List.concat (map flatten xs)</
{{out}}
Line 2,782 ⟶ 3,890:
=={{header|Suneido}}==
<
ob.Flatten()</
{{out}}
<pre>#(1, 2, 3, 4, 5, 6, 7, 8)</pre>
=={{header|
SuperCollider has the method "flat", which completely flattens nested lists, and the method "flatten(n)" to flatten a certain number of levels.
<syntaxhighlight lang="supercollider">
a = [[1], 2, [[3, 4], 5], [[[]]], [[[6]]], 7, 8, []];
a.flatten(1); // answers [ 1, 2, [ 3, 4 ], 5, [ [ ] ], [ [ 6 ] ], 7, 8 ]
a.flat; // answers [ 1, 2, 3, 4, 5, 6, 7, 8 ]
</syntaxhighlight>
Written as a function:
<syntaxhighlight lang="supercollider">
(
f = { |x|
var res = res ?? List.new;
if(x.isSequenceableCollection) {
x.do { |each|
res.addAll(f.(each))
}
} {
res.add(x);
};
res
};
f.([[1], 2, [[3, 4], 5], [[[]]], [[[6]]], 7, 8, []]);
)</syntaxhighlight>
=={{header|Swift}}==
=== Recursive ===
<syntaxhighlight lang="swift">func list(s: Any...) -> [Any] {
return s
}
Line 2,822 ⟶ 3,953:
println(s)
let result : [Int] = flatten(s)
println(result)</
{{out}}
<pre>
Line 2,831 ⟶ 3,962:
More functionally:
{{works with|Swift|1.2+}}
<
return s
}
Line 2,859 ⟶ 3,990:
println(s)
let result : [Int] = flatten(s)
println(result)</
{{out}}
<pre>
Line 2,866 ⟶ 3,997:
</pre>
=== Non-recursive ==
{{works with|Swift|2.0+}}
<syntaxhighlight lang="swift">func list(s: Any...) -> [Any]
{
return s
Line 2,916 ⟶ 4,045:
let result: [Int] = flatten(input)
print(result)</
{{out}}
<pre>
[[1], 2, [[3, 4], 5], [[[]]], [[[6]]], 7, 8, []]
[1, 2, 3, 4, 5, 6, 7, 8]
</pre>
=={{header|Tailspin}}==
<syntaxhighlight lang="tailspin">
templates flatten
[ $ -> # ] !
when <[]> do
$... -> #
otherwise
$ !
end flatten
[[1], 2, [[3, 4], 5], [[[]]], [[[6]]], 7, 8, []] -> flatten -> !OUT::write
</syntaxhighlight>
{{out}}
<pre>
[1, 2, 3, 4, 5, 6, 7, 8]
</pre>
=={{header|Tcl}}==
<
for {set old {}} {$old ne $list} {} {
set old $list
Line 2,933 ⟶ 4,079:
puts [flatten {{1} 2 {{3 4} 5} {{{}}} {{{6}}} 7 8 {}}]
# ===> 1 2 3 4 5 6 7 8</
Note that because lists are not syntactically distinct from strings, it is probably a mistake to use this procedure with real (especially non-numeric) data. Also note that there are no parentheses around the outside of the list when printed; this is just a feature of how Tcl regards lists, and the value is a proper list (it can be indexed into with <code>lindex</code>, iterated over with <code>foreach</code>, etc.)
Another implementation that's slightly more terse:
<
while { $data != [set data [join $data]] } { }
return $data
}
puts [flatten {{1} 2 {{3 4} 5} {{{}}} {{{6}}} 7 8 {}}]
# ===> 1 2 3 4 5 6 7 8</
=={{header|
<syntaxhighlight lang="trith">[[1] 2 [[3 4] 5] [[[]]] [[[6]]] 7 8 []] flatten</syntaxhighlight>
{{omit from|UNIX Shell}}
=={{header|TXR}}==
An important builtin.
<
@(bind bar foo)
@(flatten bar)</
Run:
Line 2,977 ⟶ 4,120:
bar[6]="7"
bar[7]="8"</pre>
=={{header|Uiua}}==
Keep joining elements until we're done.
<syntaxhighlight lang="Uiua">
⍥/◇⊂∞{{1} 2 {{3 4} 5} {{{}}} {{{6}}} 7 8 {}}
</syntaxhighlight>
=={{header|VBScript}}==
Line 2,982 ⟶ 4,131:
=====Implementation=====
<syntaxhighlight lang="vb">
class flattener
dim separator
Line 3,015 ⟶ 4,164:
end property
end class
</syntaxhighlight>
=====Invocation=====
<syntaxhighlight lang="vb">
dim flat
set flat = new flattener
flat.itemSeparator = "~"
wscript.echo join( flat.flatten( array( array( 1 ),2,array(array(3,4),5),array(array(array())),array(array(array(6))),7,8,array())), "!")
</syntaxhighlight>
{{out}}
Line 3,032 ⟶ 4,181:
=====Alternative (classless) Version=====
{{works with|Windows Script Host|*}}
<syntaxhighlight lang="vbscript">
' Flatten the example array...
a = FlattenArray(Array(Array(1), 2, Array(Array(3,4), 5), Array(Array(Array())), Array(Array(Array(6))), 7, 8, Array()))
Line 3,048 ⟶ 4,197:
Next
End Sub
</syntaxhighlight>
=={{header|V (Vlang)}}==
{{trans|PL/I}}
<syntaxhighlight lang="Zig">
fn main() {
arr := "[[1], 2, [[3, 4], 5], [[[]]], [[[6]]], 7, 8, []]"
println(convert(arr))
}
fn convert(arr string) []int {
mut new_arr := []int{}
for value in arr.replace_each(["[","","]",""]).split_any(", ") {if value !="" {new_arr << value.int()}}
return new_arr
}
</syntaxhighlight>
{{out}}
<pre>
[1, 2, 3, 4, 5, 6, 7, 8]
</pre>
=={{header|Wart}}==
Here's how Wart implements <code>flatten</code>:
<
if no.seq
acc
Line 3,058 ⟶ 4,227:
(cons seq acc)
:else
(flatten car.seq (flatten cdr.seq acc))</
{{out}}
<pre>(flatten '((1) 2 ((3 4) 5) ((())) (((6))) 7 8 ()))
=> (1 2 3 4 5 6 7 8)</pre>
=={{header|WDTE}}==
<syntaxhighlight lang="wdte">let a => import 'arrays';
let s => import 'stream';
let flatten array =>
a.stream array
-> s.flatMap (@ f v => v {
reflect 'Array' => a.stream v -> s.flatMap f;
})
-> s.collect
;</syntaxhighlight>
'''Usage:'''
<syntaxhighlight lang="wdte">flatten [[1]; 2; [[3; 4]; 5]; [[[]]]; [[[6]]]; 7; 8; []] -- io.writeln io.stdout;</syntaxhighlight>
{{out}}
<pre>[1; 2; 3; 4; 5; 6; 7; 8]</pre>
=={{header|Wren}}==
{{libheader|Wren-seq}}
A method already exists for this operation in the above module.
<syntaxhighlight lang="wren">import "./seq" for Lst
var a = [[1], 2, [[3, 4], 5], [[[]]], [[[6]]], 7, 8, []]
System.print(Lst.flatten(a))</syntaxhighlight>
{{out}}
<pre>
[1, 2, 3, 4, 5, 6, 7, 8]
</pre>
=={{header|zkl}}==
<
fcn(i){ if(List.isType(i)) return(Void.
flatten(L(L(1), L(2), L(L(3,4), 5), L(L(L())), L(L(L(6))), 7, 8, L()))
//-->L(1,2,3,4,5,6,7,8)</
This works by recursively writing the contents of lists to a new list. If a list is recursive or cyclic, it will blow the stack and throw an exception.
|