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

时间:2011-08-23 04:19:23

标签: coffeescript

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

4 个答案:

答案 0 :(得分:17)

这些实际上是Javascript 1.6的一部分,并且在CoffeeScript中的工作原理相同。您需要someevery

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

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

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

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

答案 1 :(得分: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

?=用于“存在分配”,仅在该属性为null / undefined时运行。

答案 2 :(得分:6)

结帐underscore.js,它为您提供将在任何主要JS环境中运行的_.any_.all方法(a.k.a。_.some_.every)。以下是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

(这些取决于_.each,这是一种简单的迭代方法,而_.breakLoop只会引发异常。)

答案 3 :(得分:0)

我今天看着这个并决定实施all作为折叠,我想你也可以为any做同样的事情(但它不会短路,或者它也不会短路):

all = (someArray, predicate) ->
  reduceAll = (left, right) ->
    return left and right
  return [predicate(elem) for elem in someArray].reduce(reduceAll, true)

非短路any大致相似:

reduceAny = (left, right) ->
    return left or right
[p(elem) for elem in someArray].reduce(reduceAny, false)

我这样做了all因为我发现它是可读的。另外,我只是将其作为自由浮动函数而不是数组方法。