Partition overload that supports creating more than two observables based on index returned #7420
Replies: 4 comments 3 replies
-
I do not think that's possible. Overloads are calculated at runtime, and I don't see any way to calculate the length of an array. It might make sense to pass the length as a separate parameter. const observableValues = of(1, 2, 3, 4, 5, 6);
const [low$, mid$, high$] = partition(observableValues, someFn, 3); |
Beta Was this translation helpful? Give feedback.
-
If an overload would not work, what about a new function named |
Beta Was this translation helpful? Give feedback.
-
I was inspired by the Reduce version: constructor(fileList: FileList){
const files = Array.from(fileList);
const [filtered, folders, invalidFiles] = files.reduce((array, file) => {
const group = this.isFolder(file) ? 1 : this.isInvalid(file) ? 2 : 0;
Array.isArray(array[group]) ? array[group].push(file) : array[group] = [file];
return array;
}, [] as File[][]);
} Some experimental RxJs version, I'm not using For now export function indexPartition<T>(
source: Observable<T>,
predicate: (value: T, index: number) => number,
partitions=3
): Observable<T>[] {
const observables: Observable<T>[] = [];
const share$ = source.pipe(shareReplay(1));
for (let i = 0; i < partitions; i++) {
observables.push(share$.pipe(filter((emission, index) => predicate(emission, index) === i)))
}
return observables;
}
constructor(fileList: FileList){
const files = Array.from(fileList);
const [filtered, folders, invalidFiles] = indexPartition(from(files), file => this.isFolder(file) ? 1 : this.isInvalid(file) ? 2 : 0);
filtered.subscribe(a => console.log("a: " + a));
folders.subscribe(b => console.log("b: " + b));
invalidFiles.subscribe(c => console.log("c: " + c));
} You could go even further and accept a export function groupPartition<T>(
source: ObservableInput<T>,
predicate: (value: T, index: number) => number|string,
keys: number|unknown[] = 3
): ObservableInput<T>[] {
const share$ = from(source).pipe(shareReplay(1));
const partitions: unknown[] = Array.isArray(keys)
? keys
: [...Array(keys).keys()]
return partitions.map(partition => share$.pipe(
filter((emission, index) => predicate(emission, index) === partition)
));
}
constructor(fileList: FileList){
const files = Array.from(fileList);
const [a$,b$,c$] = groupPartition(
from(files),
file=> this.isFolder(file) ? 1 : this.isInvalid(file) ? 2 : 0
);
a$.subscribe(a => console.log("a: " + a));
b$.subscribe(b => console.log("b: " + b));
c$.subscribe(c => console.log("c: " + c));
const [d$,e$,f$] = groupPartition(
from(files),
file=> this.isFolder(file) ? 'folder' : this.isInvalid(file) ? 'invalid' : 'file',
['folder', 'invalid', 'file']
);
d$.subscribe(a => console.log("a: " + a));
e$.subscribe(b => console.log("b: " + b));
f$.subscribe(c => console.log("c: " + c));
} |
Beta Was this translation helpful? Give feedback.
-
Otherwise, it's just |
Beta Was this translation helpful? Give feedback.
-
Currently we can use
partition
to create two observables based ontrue/false
.docs:
I would like to introduce a new overload that would return a numeric value, which should be considered the index of return array.
Would result in
Beta Was this translation helpful? Give feedback.
All reactions