Javascript 在这种情况下,如何实现函数循环语句而不是for循环?

Javascript 在这种情况下,如何实现函数循环语句而不是for循环?,javascript,for-loop,functional-programming,Javascript,For Loop,Functional Programming,如何使用函数循环语句(map、forEach、reduce)而不是for循环来检查数组中是否存在数组中任意两个元素的总和 例如,像这样的数组 [1, 2, 9, 4, 3] // would return true as 1 + 2 = 3 [2,7,12,6,8,20] // true as 2 + 6 = 8 which is enough to make it true [1, 2, 4, 9] //would return false 我可以通过for循环来实现这一点: const

如何使用函数循环语句(map、forEach、reduce)而不是for循环来检查数组中是否存在数组中任意两个元素的总和

例如,像这样的数组

[1, 2, 9, 4, 3] // would return true as 1 + 2 = 3
[2,7,12,6,8,20]  // true as 2 + 6 = 8 which is enough to make it true
[1, 2, 4, 9] //would return false
我可以通过for循环来实现这一点:

const checkSumExist = arr => {
  for(let i = 0; i < arr.length; i++) {
    for(let j = i + 1; j < arr.length; j++) {
      if(arr.includes(arr[i] + arr[j])) return true;   
    }
  }

  return false; 
}
const checkSumExist=arr=>{
for(设i=0;i

那么,在这种情况下,有没有使用函数循环语句而不是嵌套for循环的解决方案呢?

我不确定这是否是正确的解决方案,因为我不太理解函数循环的含义,但请检查一下,这个解决方案没有任何循环

function check(list, i, j) {
    if(i >= list.length || j >= list.length) return false;
    if(i != j && list.includes(list[i] + list[j])) return true;
    return check(list, i+1, j) || check(list, i, j+1)
}

check([1,2,9,4,3], 0, 0)
true

check([1,2, 4, 9], 0, 0)
false
编辑——我忘记了
。有些
提供每个元素的索引作为第二个参数。这使它更干净了一点

constfoo=[1,2,9,4,3];//将返回真值
常数条=[1,2,4,9];//将返回false
常数baz=[2,7,12,6,8,20];//也应该是真的
const sum2exists=(arr)=>{
//在arr中创建一个散列值,以便我们可以检查
//在O(1)时间内接受条件
常量哈希=arr.reduce((acc,n)=>{
acc[n]=真;
返回acc;
}, {});
//找到一些n,m,其中n和m不是相同的条目
//n+m之和为arr(使用散列)
返回arr.some((n,i)=>arr.some((m,j)=>j>i&&hash[n+m]);
};
console.log(sumfoo)
console.log(存在(条))

console.log(sumof(baz))
以下解决方案的想法是使用
reduce
map
构建2个数字的所有可能组合,然后使用
some
测试数组中是否存在任何组合的总和

函数存在(arr){
返回arr
.reduce((acc,curr,i)=>acc.concat(arr.slice(i+1).map(e=>[curr,e]),[]))
.一些([a,b])=>arr.包括(a+b));
}
log(sumExists([1,2,9,4,3]);
log(sumExists([2,7,12,6,8,20]);

log(sumExists([1,2,4,9])简化的实现-

const main=(xs=[])=>
xs.some((n,i)=>
xs.some((m,j)=>
i)
也许这是一个蛮力和过度设计的解决方案,但我向自己提出了挑战,要提供一个普通的JS,纯功能的方法来解决这个问题

顺便说一句,那里有像or或许多其他库,这将节省我答案中的样板部分

它只是有一个问题:它检查所有可求和的组合(
可能的组合
),但这是一个加号,因为可以打印出所有的巧合。此外,还有
somesumeexists
,它只检查
possibleSums
是否输出一个或多个一致性

另一方面,它还有另一个问题:它依赖于输入不会包含重复的数字这一事实

/::组合器:
//I::a->a->a
常数I=x=>x
//T::a->(a->a)->a
常数T=x=>f=>f(x)
//W::a->(a->a->a)->a
常数W=x=>f=>f(x)(x)
//::非通用、部分函子、链、应用程序数组特定实例…::
//地图::(a->a)->[a]->[a]
常量map=f=>xs=>xs.map(f)
//链::(a->a)->[a]->[a]
常量链=f=>xs=>xs.reduce((o,x)=>[…o,…f(x)],[])
//ap::[a->b]->[a]->[b]
常量ap=ms=>m=>chain(x=>map(f=>f(x))(ms))(m)
//lift2::[a->c->d]->[a->b]->[b->c]->[d]
常量lift2=f=>xs=>ys=>ap(map(f)(xs))(ys)
//加入::[[a]]->[a]
常量连接=链(I)
//::Utils:::
//管道::[Any->Any]->Any->Any
constpipe=xs=>x=>xs.reduce((x,f)=>f(x,x)
//任意::(a->Boolean)->[a]->Boolean
const any=f=>xs=>xs.some(f)
//joinWith::String->[Any]->[String]
const joinWith=sep=>xs=>xs.join(sep)
//长度::[任意]->数字
常量长度=xs=>xs.length
//等于::a->a->布尔值
常数=x=>y=>x==y
//not::a->Boolean
常数不=x=>x!==真的
//可能数::数字->[[数字,数字,数字]]
常量可能值=输入=>
烟斗([
W
T(lift2(x=>y=>x!==y&&input.includes(x+y)?[[x,y,x+y]]:[]),
参加
])(输入)
//someSumExists::[Number]->Boolean
const someSumExists=管道[
可能的,
长度,
等于(0),
不
])
//打印总数::[[Number,Number,Number]]->[String]
常量printSums=管道([
map(([x,y,r])=>`${x}+${y}=${r}`),
joinWith('\n')
])
//printPossibleSums::[[Number,Number,Number]]->String
常量printPossibleSums=管道([possibleSums,printSums])
常量输入1=[1,2,9,4,3]
常量输入2=[2,7,12,6,8,20]
常量输入3=[1,2,4,9]
常量输出1=打印可能性(输入1)
const output1_u2;=someSumExists(input1)
常量输出2=打印可能性(输入2)
const output2_u2;=somesumeexists(input2)
常量输出3=打印可能性(输入3)
const output3_u3;=someSumExists(input3)
console.log('输入1有一个大小写:',输出1_389;)
console.log(output1)
console.log('输入2有一个大小写:',输出2_389;)
console.log(输出2)
console.log('Input 3有一个case:',output3\)

console.log(output3)
这是我使用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));

我的结论是,与迭代编程相比,FP很难实现,而且解决方案过于复杂:)。如果有人可以简化,我愿意提出建议或更正。

函数循环语句映射、forEach、reduce..您现在正在执行递归!!我认为您的解决方案是不正确的,因为您只检查了正好2个元素,而不是“至少两个元素的和”。@slider这是正确的,如果数组中存在任何两个元素的和,则应返回true,仅返回两个el