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)仍然有效,显然比抛出错误法好多了
唯一需要注意的是,因为置空的副作用,部分情况要先对数组做浅拷贝
1
autoxbc OP 改进一下例子
```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; } }) ``` |
2
kx5d62Jn1J9MjoXP 2018-12-31 22:04:30 +08:00 via Android 1
学点函数式编程就知道你这做法不好了
要达到你这效果,简单的做法是先 take until > 3, 然后该干嘛干嘛 |
3
lastpass 2018-12-31 22:25:45 +08:00 via Android
system.exot()
|
4
lastpass 2018-12-31 22:26:20 +08:00 via Android
o --> i
|
5
congeec 2018-12-31 22:31:17 +08:00 via iPhone
二楼说得对,你需要 takewhile 函数
|
6
will0404 2018-12-31 22:31:37 +08:00 via Android
这些方法不应该有 side effort。
|
7
will0404 2018-12-31 22:32:51 +08:00 via Android
effort -> effect
|
8
zealot0630 2018-12-31 23:02:05 +08:00 1
unfold 可以,然而这个函数太难驾驭,大部分库和语言都不支持。
https://srfi.schemers.org/srfi-1/srfi-1.html#FoldUnfoldMap 随便写了个 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 调用,在一行里面实现。 |
9
zealot0630 2018-12-31 23:25:34 +08:00 1
JS 的 iterator 是 mutable 的,简直反设计,下面是个能跑的实现和例子
https://gist.github.com/kghost/b001d39b6c6b541a289774bf137f2da8 第一个参数 p 决定什么时候跳出来,楼主按照需求实现 p 函数就可以了 |
10
Justin13 2019-01-01 09:00:12 +08:00 via Android
乱改属性可是大忌。可以学学 haskell
|
11
msg7086 2019-01-01 09:37:12 +08:00
没过几个月,楼主就被后来接手的程序员打死了。
|
12
lihongjie0209 2019-01-01 09:45:23 +08:00
瞎搞
|
13
plqws 2019-01-01 09:51:52 +08:00 1
在操作前先 slice 不好吗
|
14
tinywhale 2019-01-01 12:35:03 +08:00
我觉得你想要的效果是 elixir 里的 `Enum.reduce_while/3`,我偶尔也觉得 js array 应该有个类似的,后来觉得如果要这样的效果还不如直接 for loop
|
15
codeduan 2019-01-02 10:32:20 +08:00
一般来说用 some 已经够了,不行的话就用 for loop 吧。
|
16
ghostheaven 2019-01-25 09:01:23 +08:00 via Android
用 generator 重新实现那几个函数,自己定义一个用于结束的 Symbol,当 yield 这个 Symbol 的时候循环结束,并返回默认值
|