Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get a flattened tuple type of a tuple of tuples?

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?

like image 235
Pedro A Avatar asked Aug 24 '20 19:08

Pedro A


People also ask

How do you flatten a nested tuple?

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.

How do you determine the shape of a tuple?

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.

How to get the type of tuples?

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.

How to flatten a list of tuples into a string format?

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).

What is the difference between a tuple and a value tuple?

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.

What is the difference between the original and flattened tuple?

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.


Video Answer


1 Answers

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.

like image 147
Titian Cernicova-Dragomir Avatar answered Oct 28 '22 06:10

Titian Cernicova-Dragomir