This is my solution using Rxjs:
import { Observable, from, of, zip, pairs, combineLatest, empty } from 'rxjs';
import { filter, map, takeUntil, takeWhile, single, zipAll, pairwise, combineAll, mergeMap, merge, first, skip, skipWhile, defaultIfEmpty } from 'rxjs/operators';
let test1 = [1, 2, 9, 4, 3]; // would return true as 1 + 2 = 3
let test2 = [2,7,12,6,8,20]; // true as 2 + 6 = 8 which is enough to make it true
let test3 = [1, 2, 4, 9]; //would return false
let observable1 = from(test1);
let skipSameIndex = (arr:number[], anchorIndex:number) => {
return from(arr).pipe(
filter((v, i) => {
// console.log('anchodIndex:', anchorIndex, ', i:', i);
return anchorIndex !== i;
})
)
}
let pairAll = (arr:number[]) => from(arr).pipe(mergeMap( (x, index) => {
return combineLatest(of(x), skipSameIndex(arr, index))
}));
let isPairExistsInArray = (pair:[number, number], arr: number[]) => {
let isExists = arr.indexOf(pair[0] + pair[1]) >= 0;
// console.log('pair:', pair, ', isExists:', isExists);
return isExists;
}
let isSumEachElementsExists = (arr:number[]) => pairAll(arr).pipe(
map((pair:[number, number]) => isPairExistsInArray(pair, arr)),
// first(isExists => isExists)
filter(x => x),
defaultIfEmpty(false)
);
// skipSameIndex(test3, 1).subscribe(x => console.log(x));
isSumEachElementsExists(test1).toPromise()
.then(isExists => console.log('test1 isExists:', isExists))
.catch(err => console.log('ERROR:', err));
isSumEachElementsExists(test2).toPromise()
.then(isExists => console.log('test2 isExists:', isExists))
.catch(err => console.log('ERROR:', err));
isSumEachElementsExists(test3).toPromise()
.then(isExists => console.log('test3 isExists:', isExists))
.catch(err => console.log('ERROR:', err));
My conclusion after this is FP is hard and the solution is overly complex compare to iterative programming :). I am open for suggestion or correction if anyone can simplify this.