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.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
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