技术解析

偶得一法跳出数组循环
0
2021-09-02 05:06:26
idczone

some 和 every 可以用 return 值跳出循环

forEach,filter,find,findIndex,map,reduce,reduceRight 没有可用的跳出方法,continue 和 break 都不能用,那么怎么跳出这些数组循环?

网上搜索了一下,只见到一种构造 try catch 结构然后 throw 的方法,一点也不优雅

用于循环的数组自身消失的话,循环不就自然中止了

[1,2,3,4,5].forEach( (val,idx,arr) => {
    if( val > 3 )
        return arr.length = 0 ;
    console.log(val);
} );

跳出过程并未本质改变这些循环的语义,所有的返回值(比如 reduce)仍然有效,显然比抛出错误法好多了

唯一需要注意的是,因为置空的副作用,部分情况要先对数组做浅拷贝


改进一下例子
```js
[1, 2, 3, 4, 5].forEach((val, idx, arr) => {
if (val < 3){
console.log(`${val} < 3`);
}
else {
console.log(`${val} >= 3`);
arr.length = 0;
}
})
```

学点函数式编程就知道你这做法不好了
要达到你这效果,简单的做法是先 take until > 3, 然后该干嘛干嘛

system.exot()

o --> i

二楼说得对,你需要 takewhile 函数

这些方法不应该有 side effort。

effort -> effect

unfold 可以,然而这个函数太难驾驭,大部分库和语言都不支持。
https://srfi.schemers.org/srfi-1/srfi-1.html/>随便写了个 js 实现:
···
function unfold(p, f, g, seed, reduce, tailgen) {
function recursive(iter) {
if (p(iter)) return tailgen(iter);
return reduce(f(iter), recursive(g(iter)));
}
return recursive(seed);
}
···
举一个简单的例子,比如说把一个数组累加起来:
···
sum(a) = unfold(
(e) => !e /* 没有元素时候终止 */,
identify /* identify 函数,返回元素本身 */,
(iter) => iter.nex() /* generator,如何遍历元素 */
a[@@iterator]() /* 种子,数组的迭代器 */
(head, tail) => head + tail /* reduce,如何汇总 */
(e) => 0 /* 如何处理尾巴,也可以理解为初始值 */
)
```
unfold 功能相当强大,你要问有多强大,他是其他所有容器函数( forEach,filter,find,findIndex,map,reduce,reduceRight )的母亲,这些函数都能用一个 unfold 调用,在一行里面实现。

JS 的 iterator 是 mutable 的,简直反设计,下面是个能跑的实现和例子
https://gist.github.com/kghost/b001d39b6c6b541a289774bf137f2da8

乱改属性可是大忌。可以学学 haskell

没过几个月,楼主就被后来接手的程序员打死了。

瞎搞

在操作前先 slice 不好吗

我觉得你想要的效果是 elixir 里的 `Enum.reduce_while/3`,我偶尔也觉得 js array 应该有个类似的,后来觉得如果要这样的效果还不如直接 for loop

一般来说用 some 已经够了,不行的话就用 for loop 吧。

用 generator 重新实现那几个函数,自己定义一个用于结束的 Symbol,当 yield 这个 Symbol 的时候循环结束,并返回默认值

数据地带为您的网站提供全球顶级IDC资源