Consider I have a tuple of tuples:
type Example = [[3,5,7], [4,9], [0,1,10,9]];
I want to create an utility type Flatten<T>
such that Flatten<Example>
gives:
type FlatExample = Flatten<Example>;
// type FlatExample = [3,5,7,4,9,0,1,10,9];
For my use case, you can assume the tuple is nested only one level deep. The tuples can have any size.
How can I do this?
Flattening Nested Tuples To solve the problem is by finding all the nested tuples in each tuple element of the container. And then flatten it to a normal tuple with all elements of the nested as individual elements.
The shape of a simple Python tuple or list can be obtained with the built-in len() function. len() will return an integer that describes the number of objects in the tuple or list. This procedure gets more complicated for a tuple of tuples or a list of lists. You can think of these as 2-dimensional tuples or lists.
Tuples can be a collection of various data types, and unlike simpler data types, conventional methods of getting the type of each element of tuple is not possible. For this we need to have different ways to achieve this task.
When it is required to flatten a list of tuples into a string format, the 'str' method and the 'strip' method can be used. A list can be used to store heterogeneous values (i.e data of any data type like integer, floating point, strings, and so on).
The main differences are as follows: 1 ValueTuple types are value types. Tuple types are reference types. 2 ValueTuple types are mutable. Tuple types are immutable. 3 Data members of ValueTuple types are fields. Data members of Tuple types are properties.
The original tuple : ( [5, 6], [6, 7, 8, 9], [3]) The flattened tuple : (5, 6, 6, 7, 8, 9, 3) Writing code in comment? Please use ide.geeksforgeeks.org , generate link and share the link here.
To do this you would require recursive conditional types. This will be fully supported in 4.1:
type Example = [[3,5,7], [4,9], [0,1,10,9]];
type Flatten<T extends any[]> =
T extends [infer U, ...infer R] ? U extends any[] ? [...U, ... Flatten<R>]: []: []
type FlatExample = Flatten<Example>;
Playground Link
Edit
Simpler version, curtesy of jcalz:
type Example = [[3,5,7], [4,9], [0,1,10,9]];
type Flatten<T extends any[]> =
T extends [any, ...infer R] ? [...T[0], ... Flatten<R>]: []
type FlatExample = Flatten<Example>;
Playground Link
/Edit
You can hack a version even today (the extra indirection is needed to fool the compiler into allowing the recursive conditional type, conceptually this is equivalent to the simpler above version):
type Example = [[3, 5, 7], [4, 9], [0, 1, 10, 9]];
type Flatten<T extends any[]> = T extends [infer U, ...infer R] ? {
1: U extends any[] ? [...U, ...Flatten<R>] : [],
2: []
}[U extends any[] ? 1 : 2] : [];
type FlatExample = Flatten<Example>;
Playground Link
Just for fun, the 4.1, generalized flattening version.
type Example = [[3,5,7], [4,9, [10, 12, [10, 12]]], [0,1,10,9, [10, 12]]];
type Flatten<T extends any[]> =
T extends [infer U, ...infer R] ?
U extends any[] ?
[...Flatten<U>, ... Flatten<R>]: [U, ... Flatten<R>]: []
type FlatExample = Flatten<Example>;
Playground Link
Note: While recursive types are more supported in 4.1, you can still run into compiler hardcoded limits, such as type instantiation depth, and total type instances (as such recursive types generate a lot of type instantiations). So use sparingly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With