如何使用for循环输出bool

时间:2017-12-27 23:14:09

标签: c# for-loop

我一直在尝试使用for循环来检查数组中是否存在元素。我似乎无法弄清楚如何做到这一点,因为在for循环内声明的所有变量都无法从其范围之外访问。我该如何正确地做到这一点?

var array = new[] { 3, 4, 2, 6, 3 };
var value = 2;

bool isContained;
for(var i = 0; i < array.Length; i++)
    isContained = (value == array[i]);

if(isContained)
    Console.WriteLine("The value is in the array");
else
    Console.WriteLine("The value is not in the array");

8 个答案:

答案 0 :(得分:8)

除了这样的事实之外,你的代码甚至不能编译,因为isContained可能永远不会被初始化,问题是你会在{{一遍又一遍地覆盖isContained。 1}}循环:

for

基本上,当且仅当您找到了正确的值时才需要设置它。所以基本的工作版本是:

bool isContained;
for(var i = 0; i < array.Length; i++)
    isContained = (value == array[i]);

显然,一旦遇到匹配,迭代数组的其余部分是没有意义的。因此,这稍微好一些:

bool isContained = false;
for(var i = 0; i < array.Length; i++)
{
    if (value == array[i]) isContained = true;
}

这是理解这个概念的好方法。然而,正如有人在评论中指出的那样,存在一种更为先进的解决方案,即“一线”:

bool isContained = false;
for(var i = 0; i < array.Length; i++)
{
    if (value == array[i])
    {
        isContained = true;
        break;
    }
}

答案 1 :(得分:2)

问题是您的isContained值会在每次迭代中被覆盖。您的代码应按如下方式编写:

Boolean isContained = false;

for (Int32 i = 0; i < array.Length; ++i)
{
    if (value == array[i])
    {
        isContained = true;
        break; // no need further processing, you found it
    }
}

旁注...为什么不使用Enumerable.Contains()

Int32[] array = new Int32[] { 3, 4, 2, 6, 3 };
Int32 value = 2;

if (array.Contains(value))
    Console.WriteLine("The value '{0}' has been found in the array!", value);

LINQ解决方案如下:

Int32[] array = new Int32[] { 3, 4, 2, 6, 3 };
Int32 value = 2;

if (array.Any(x => x == value))
    Console.WriteLine("The value '{0}' has been found in the array!", value);

答案 2 :(得分:1)

尝试从循环内部返回。

for(var i = 0; i < array.Length; i++)
{
    if(value == array[i])
    {
        Console.WriteLine("The value is in the array");
        return;
    }
}

Console.WriteLine("The value is not in the array");

答案 3 :(得分:1)

您的代码有三个问题。

首先,编译器无法检测到肯定会分配isContained。考虑数组是否为空;然后永远不会设置isContained,使用尚未设置的值是不合法的。编译器必须是相对本地的,以确定是否已经设置了一个值(如果它更聪明,我们最终会遇到很难解决为什么允许它们的情况),所以这是一个禁忌。

当然如果确实发生了数组是空的,我们应该得到一个结果,应该是false

我们可以通过将值设置为false

来解决这两个问题
var array = new[] { 3, 4, 2, 6, 3 };
var value = 2;

bool isContained = false;
for (var i = 0; i < array.Length; i++)
    isContained = (value == array[i]);

if (isContained)
    Console.WriteLine("The value is in the array");
else
    Console.WriteLine("The value is not in the array");

它给了我们错误的答案,揭示了第三个问题;因为isContained一直在写它只告诉我们最后的答案。解决此问题的一种方法是使用|=,以便将false设置为true,但不能为false:

var array = new[] { 3, 4, 2, 6, 3 };
var value = 2;

bool isContained = false;
for (var i = 0; i < array.Length; i++)
    isContained |= (value == array[i]);

if (isContained)
    Console.WriteLine("The value is in the array");
else
    Console.WriteLine("The value is not in the array");

这有效,但很浪费。一旦我们知道数值在数组中,如果我们查看0,2或10亿个值并不重要;答案是真的。所以我们应该停止寻找:

var array = new[] { 3, 4, 2, 6, 3 };
var value = 2;

bool isContained = false;
for (var i = 0; i < array.Length; i++)
{
    if (value == array[i])
    {
        isContained = true;
        break;
    }
}

if (isContained)
    Console.WriteLine("The value is in the array");
else
    Console.WriteLine("The value is not in the array");

这可以更快地为我们提供正确的答案。

顺便提一下,一个值得了解的更简单的版本是使用Contains()来解决这些问题:

if (array.Contains(value))
    Console.WriteLine("The value is in the array");
else
    Console.WriteLine("The value is not in the array");

或更一般地Any()可以询问有关集合的更灵活的问题:

if (array.Any(x => x == value))
    Console.WriteLine("The value is in the array");
else
    Console.WriteLine("The value is not in the array");

能够自己循环,但仍然是一个重要的技术知识。它也是最快的,尽管差别很小,只有在紧密循环中才有意义:继续学习for循环,直到你对它们充满信心,然后使用更简洁和不言自明的Contains或适用时Any,但性能关键点除外。

答案 4 :(得分:1)

虽然你要求for循环,但无限时间可能会更好。就个人而言,我发现while循环更具表现力和表达能力。这个概念或者前提是当循环迭代时,一旦找到匹配就会停止。

在我看来,for循环的功能几乎完全相同,但在执行此循环时,显式操作将随之而来。如果for循环很快,遍历一个集合,那么就会有一个动作。

大多以短语或快速浏览的方式,您很快就会有意图。

int index = 0;
int value = 9;
bool valid = false;

while(collection.length != index)
{
     if(value == collection[index])
     {
          valid = true;
          break;
     }

     index++
}

你也可以通过更具表现力的Linq实现这一目标。

int value = 9;
var valid = collection.Any(item => item == value);

就我个人而言,我发现any和while更具表现力和自我记录的用例。

答案 5 :(得分:0)

  

我似乎无法弄清楚如何执行此操作,因为在for循环内声明的所有变量都无法从其范围之外访问

你是什​​么意思?您的代码有问题,但没有一个涉及无法访问for循环内声明的变量。

您发布的代码应该接近成功编译。它确实有几个问题:

  1. 主要原因是您没有初始化isContained。这将导致编译器发出CS0165,“使用未分配的局部变量”。使用初始化声明变量:bool isContained = false;
  2. 此外,您一直在设置isContained,所以最后得到的只是数组中的 last 元素是否是您正在寻找的。请尝试isContained |= (value == array[i]);,或类似:
  3. if (value == array[i])
    {
        isContained = true;
        break;
    }
    

    这比仅使用|=运算符更冗长,但它确实会提前终止循环。

    当然,如果你只是想获得价值,并且不想学习如何编写这样的循环,你可以使用内置的Enumerable.Contains()方法:

    bool isContained = array.Contains(value);
    

答案 6 :(得分:0)

我知道这已经被解决了......但是

  

这里有很多方法可以实现你想要的,它的好处   了解所有这些变体,因为它们将成为面包和黄油   您将来设计的几乎所有算法

鉴于这些变量

var array = new[] { 3, 4, 2, 6, 3 };
var value = 2;
var isFound = false;

您可以使用for循环

for (var i = 0; i < array.Length; i++) // loop to the end of the array
{
    if (array[i] == value) // comparison
    {
        isFound = true;    // we found
        break;             // We can exit the loop early
    }
}

// Write our results
Console.WriteLine($"Found = {isFound}");

您可以使用foreach循环

foreach (var element in array) // loop to the end of the array
{
    if (element == value) // comparison
    {
        isFound = true;    // we found
        break;             // We can exit the loop early
    }
}

// Write our results
Console.WriteLine($"Found = {isFound}");

您可以使用while循环

var index = 0;
while (index < array.Length) // loop to the end of the array
{
    if (array[index] == value) // comparison
    {
        isFound = true;        // we found
        break;                 // We can exit the loop early
    }
    index++;                   //++ is just a fancy way of saying Add one now before comparison
}

// Write our results
Console.WriteLine($"Found = {isFound}");

您可以使用do while循环

var index = 0;
do // loop to the end of the array
{
    if (array[index] == value) // comparison
    {
        isFound = true;        // we found
        break;                 // We can exit the loop early
    }
} while (++index < array.Length);//  ++ is just a fancy way of saying Add one now before comparison

您可以使用Linq Any

// a fancy way of saying, does any element in the array match the value
isFound = array.Any(element => element == value);

// Write our results
Console.WriteLine($"Found = {isFound}");

您可以使用Linq Contains

// a fancy way of saying does the array contain your value
isFound = array.Contains(value);

// Write our results
Console.WriteLine($"Found = {isFound}");

其他资源

for (C# Reference)

foreach, in (C# Reference)

while (C# Reference)

do (C# Reference)

++ Operator (C# Reference)

Enumerable.Any

Enumerable.Contains

Further Reading about loops

答案 7 :(得分:-1)

您可以轻松使用List代替int[]

using System;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        List<int> list = new List<int>(){ 2, 3, 7 };

        Console.WriteLine("List size: {0}", list.Count);
        Console.WriteLine("List has '1': {0}", list.Contains(1));
        Console.WriteLine("List has '2': {0}", list.Contains(2));
        Console.WriteLine("List has '3': {0}", list.Contains(3));
    }
}