2011-08-23 34 views

回答

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 

但无论是那些具有短的电路逻辑。 编辑:但请参阅里卡多的更好版本的答案。

+0

完美答案。我只是补充说,可以使用underscore.js与旧版浏览器兼容,如下面的答案所述。 – brandizzi

+0

很容易添加短路,你忘了'?=',看到我的回答:) –

+0

@Ricardo - 是的,那样更好。此外,我不知道?=诡计,所以这非常整齐。 – 2011-08-24 16:49:30

5

退房underscore.js,它为您提供了_.any_.all方法(又名_.some_.every)将在任何重大JS环境中运行。这里是他们如何在CoffeeScript中实施了underscore.coffee

_.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,这只是抛出一个异常)

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运行。

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这种方式,因为我发现它是可读的。另外,我只是做了一个自由浮动函数而不是数组方法。