很好的方式做'如果集合中的所有项目通过测试'

时间:2010-11-12 01:27:39

标签: algorithm language-design

我的意思是:

bool passed = true;
for(int i = 0; i < collection.Length; i++)
{
    if(!PassesTest(collection[i]))
    {
        passed = false;
        break;
    }
}
if(passed){/*passed code*/}

需要额外的变量,额外的测试

for(int i = 0; i < collection.Length; i++)
{
    if(!PassesTest(collection[i]))
    {
        return;
    }
}
{/*passed code*/}

整洁,但要求它是它自己的功能,如果它是自我在循环或其他东西,而不是最高效的做事方式。另外,写一个额外的功能是一种痛苦

if(passed){/*passed code*/}
for(int i = 0; i < collection.Length; i++)
{
    if(!PassesTest(collection[i]))
    {
        goto failed;
    }
}
{/*passed code*/}
failed: {}

很好,但你必须使用标签名称和难看的标签语法

for(int i = 0; ; i++)
{
    if(!(i < collection.Length))
    {
         {/*passed code*/}
         break;
    }
    if(!PassesTest(collection[i]))
    {
        break;
    }
}

可能是最好的,但仍然有点手动,有点浪费for循环结构的功能,例如,你不能用foreach做到这一点

处理这个问题最好的方法是什么?

在我看来这样的事情会很好: 的foreach(...) {     ... } finally {...} //仅在循环以常规方式结束时执行(不中断)

我错过了什么吗?因为这对我来说是一个非常普遍的问题,我并不喜欢我提出的任何解决方案。

我使用c ++和C#,因此两者中的解决方案都很棒。 但也会对其他语言的解决方案感兴趣。 (虽然在任何语言中避免这种情况的设计原则都是理想的)

7 个答案:

答案 0 :(得分:2)

您可以在.NET中使用Linq 这是C#中的一个例子:

if(collection.All(item => PassesTest(item)))
{
    // do my code
}

答案 1 :(得分:2)

如果您的语言没有此功能,请编写一个函数“forall”,它带有两个参数:一个列表和一个布尔值函数,对于列表的所有元素都是如此。那么你只需要写一次,而且它的惯用程度非常重要。

“forall”函数看起来与第二个代码示例完全相同,只是现在“collection”和“passTest”是该函数的参数。

调用forall看起来大致如下:

if (forall(myList,isGood)) {

是可读的。

作为一个额外的好处,你可以通过在否定的布尔函数上调用“forall”来实现“exists”,并否定它的答案。也就是说,“存在x P(x)”被实现为“not forall x not P(x)”。

答案 2 :(得分:0)

C ++和STL

if (std::all_of(collection.begin(), collection.end(), PassesTest))
{
    /* passed code */
}

答案 3 :(得分:0)

红宝石:

if collection.all? {|n| n.passes_test?}
  # do something
end

Clojure的:

(if (every? passes-test? collection)
  ; do something
  )

答案 4 :(得分:0)

Groovy的:

if (!collection.find { !PassesTest(it) }) {
  // do something
}

答案 5 :(得分:0)

Scala的:

def passesTest(i: Int) = i < 5 // example, would likely be idiomatically in-line
var seq = List(1,2,3,4);
seq.forall(passesTest) // => True

大多数(如果不是全部)此处提供的答案都是:高阶构造 - 例如“传递函数” - 非常非常好。如果您正在设计一种语言,请不要忘记最近60多年的编程语言/设计。

答案 6 :(得分:0)

Python(自v2.5起):

if all(PassesTest(c) for c in collection):
    do something

注意:

  • 我们可以直接迭代收集,不需要索引和查找
  • 在Python 2.5中添加了
  • all() and any() builtin functions
  • any()的参数,即PassesTest(c) for c in collection,是生成器表达式。您还可以通过添加括号[(PassesTest(c) for c in collection]
  • 将其视为列表理解
  • ... for c in collection导致迭代通过集合(或序列/元组/列表)。对于dict,请使用dict.keys()。对于其他数据类型,请使用正确的迭代器方法。