如何在Coffeescript中实现array.any()和array.all()方法?

Gav*_*vin 11 coffeescript

如何在Coffeescript中实现array.any()array.all()方法?

小智 17

这些实际上是Javascript 1.6的一部分,在CoffeeScript中也可以使用它们.你想要一些每一个.

我不知道你在哪个环境,但IE <9似乎不支持这些方法.它们很容易添加.这些页面上有一段代码可以显示兼容性代码,如果您愿意,可以将它们翻译成CoffeeScript,尽管您不必这样做.

一种更粗糙,更简单的方法(未经测试):

if not Array.prototype.some
    Array.prototype.some = (f) -> (x for x in @ when f(x)).length > 0

if not Array.prototype.every
    Array.prototype.every = (f) -> (x for x in @ when f(x)).length == @length
Run Code Online (Sandbox Code Playgroud)

但这些都没有短路逻辑.编辑:但请看里卡多的答案,以获得更好的版本.


Ric*_*asi 12

短路(优化)版本:

Array.prototype.some ?= (f) ->
  (return true if f x) for x in @
  return false

Array.prototype.every ?= (f) ->
  (return false if not f x) for x in @
  return true
Run Code Online (Sandbox Code Playgroud)

?=是"存在分配",只有当该属性是运行null/ undefined.


Tre*_*ham 6

退房underscore.js,它为您提供了_.any_.all方法(又名_.some_.every),将任何主要的JS环境中运行.以下是它们如何在underscore.coffee中的CoffeeScript中实现:

_.some = (obj, iterator, context) ->
  iterator ||= _.identity
  return obj.some iterator, context if nativeSome and obj.some is nativeSome
  result = false
  _.each obj, (value, index, list) ->
    _.breakLoop() if (result = iterator.call(context, value, index, list))
  result

_.every = (obj, iterator, context) ->
  iterator ||= _.identity
  return obj.every iterator, context if nativeEvery and obj.every is nativeEvery
  result = true
  _.each obj, (value, index, list) ->
    _.breakLoop() unless (result = result and iterator.call(context, value, index, list))
  result
Run Code Online (Sandbox Code Playgroud)

(这些依赖于_.each,这是一种简单的迭代方法,并且_.breakLoop只会引发异常.)