检查值是否在数组中(C#)


109

如何检查C#中的值是否在数组中?

像,我想创建一个带有打印机名称列表的数组。

这些将被提供给一个方法,该方法将依次查看每个字符串,如果该字符串与数组中的值相同,请执行该操作。

例如:

string[] printer = {"jupiter", "neptune", "pangea", "mercury", "sonic"};
foreach (p in printer)
{
   PrinterSetup(p);     
}

这些是打印机的名称,它们被馈送到PrinterSetup方法。

PrinterSetup看起来像这样(一些伪代码):

public void PrinterSetup(printer)
{
   if (printer == "jupiter") 
   {
      Process.Start("BLAH BLAH CODE TO ADD PRINTER VIA WINDOWS EXEC");
   }
}

如何if (printer == "jupiter")以C#可以识别的方式格式化?


4
尝试给您的参数名称指定类型(字符串),这样就可以了。
乔恩·斯基特

2
这个问题让我有些困惑。您是在问如何检查值是否在数组中,或者如何在C#中进行字符串比较吗?如果是后者,则可以使用printer.Equals("jupiter")。如果是前者,使用linqprinter.Contains("jupiter")
newfurniturey

@newfurniturey很……问题很困惑,示例代码与标题不匹配,因此答案也很困惑;为什么像这样的胡言乱语被我超越了。而且也没有必要做printer.Equals("jupiter")......的OP的代码if (printer == "jupiter")工作得很好......只要printer被宣布为一个字符串,如飞碟双向笔记。
吉姆·巴尔特

Answers:


231

添加必要的名称空间

using System.Linq;

然后你可以使用linq Contains()方法

string[] printer = {"jupiter", "neptune", "pangea", "mercury", "sonic"};
if(printer.Contains("jupiter"))
{
    Process.Start("BLAH BLAH CODE TO ADD PRINTER VIA WINDOWS EXEC"");
}

2
@ 0A0D。我认为这个答案是最简单/最短且广为人知的实现同一事物(How do I check if a value is in an array in C#?)和高效的最佳方法。没有循环没有额外的方法。只是名称空间是多余的,这不是什么大问题。
萨米(Sami)2012年

6
@Sami:Linq在内部使用循环。

2
@ 0A0D Sam可能指的是书面代码,而不是编译的指令。Linq在内部使用循环和方法,但是从编码人员的角度来看,所有隐藏的东西都不需要担心。
2012年

1
正确@ 0A0D。我的意思是编码人员/开发人员不需要右循环。阵列的偏离路线检查需要循环:)
Sami 2012年

3
这当然很容易并且值得推荐。如果您没有访问Linq的权限,或者不想使用Linq,则可以依赖数组的某些显式接口实现。从.NET 1.1开始,我们提供了((IList)printer).Contains("Jupiter")非通用的(可能是框值类型等),甚至适用于多维数组。从.NET 2.0开始,我们有了更神奇的((IList<string>)printer).Contains("Jupiter")类型安全性。Linq方法是.NET 3.5中的新增功能。
Jeppe Stig Nielsen

29
   string[] array = { "cat", "dot", "perls" };

// Use Array.Exists in different ways.
bool a = Array.Exists(array, element => element == "perls");
bool b = Array.Exists(array, element => element == "python");
bool c = Array.Exists(array, element => element.StartsWith("d"));
bool d = Array.Exists(array, element => element.StartsWith("x"));

// Display bools.
Console.WriteLine(a);
Console.WriteLine(b);
Console.WriteLine(c);
Console.WriteLine(d);
----------------------------output-----------------------------------

1)真2)假3)真4)假


6
这应该是公认的答案。如果您使用阵列,则性能并不是完全不可能的。在这种情况下,Linq通常是错误的选择。
Philm

22
if ((new [] {"foo", "bar", "baaz"}).Contains("bar"))
{

}  

这是一个一般示例-您能提供一个与问题更好匹配的示例吗?
哈兹2015年

9
这可能是一个一般示例,但这正是我所寻找的。
格兰特·伯奇迈尔

7

像这样吗

string[] printer = {"jupiter", "neptune", "pangea", "mercury", "sonic"};
PrinterSetup(printer);

// redefine PrinterSetup this way:
public void PrinterSetup(string[] printer)
{
    foreach (p in printer.Where(c => c == "jupiter"))
    {
        Process.Start("BLAH BLAH CODE TO ADD PRINTER VIA WINDOWS EXEC"");
    }
}

7
    public static bool Contains(Array a, object val)
    {
        return Array.IndexOf(a, val) != -1;
    }

2
我喜欢这个。但是,如果a是多维数组(new string[10, 20, 15]例如),则将失败,但有例外。如果未从零开始索引的一维数组(例如Array.CreateInstance(typeof(string), new[] { 5, }, new[] { -2, }),我承认,在C#中很少见),并且返回值可能错误,它也会失败。这些缺点可以通过泛型轻松解决:public static bool Contains<TElement>(TElement[] a, TElement val) { return Array.IndexOf(a, val) != -1; }
Jeppe Stig Nielsen

我喜欢这个,但只是因为它是没有LINQ和它确认的IndexOf是唯一留下来使用。
Bitterblue

6

注意:问题是关于字符串数组的。所提到的例程不应与单个字符串的.Contains方法混合使用。

由于两个原因,我想添加一个引用不同C#版本的扩展答案:

  • 接受的答案需要Linq,它完全是C#惯用的语言,但它并非没有成本,并且在C#2.0或更低版本中不可用。当涉及数组时,性能可能很重要,因此在某些情况下,您希望保留Array方法。

  • 没有答案直接涉及将这个问题放到函数中的问题(因为有些答案也在将字符串与字符串数组混合,这并不是完全不重要的)。

Array.Exists()是C#/。NET 2.0方法,不需要Linq。在数组中搜索为O(n)。为了更快地访问,请使用HashSet或类似的集合。

从.NET 3.5开始,还存在一种通用方法Array<T>.Exists()

public void PrinterSetup(string[] printer)
{
   if (Array.Exists(printer, x => x == "jupiter"))
   {
      Process.Start("BLAH BLAH CODE TO ADD PRINTER VIA WINDOWS EXEC");
   }
}

您可以编写自己的扩展方法(C#3.0及更高版本)以添加语法糖以获得与所有数组的字符串相同/相似的“ .Contains”(不包括Linq):

// Using the generic extension method below as requested.
public void PrinterSetup(string[] printer)
{
   if (printer.ArrayContains("jupiter"))
   {
      Process.Start("BLAH BLAH CODE TO ADD PRINTER VIA WINDOWS EXEC");
   }
}

public static bool ArrayContains<T>(this T[] thisArray, T searchElement)
{
   // If you want this to find "null" values, you could change the code here
   return Array.Exists<T>(thisArray, x => x.Equals(searchElement));
}

在这种情况下,ArrayContains()将使用此方法,而不使用Linq的Contains方法。

提到的其他地方。contains方法是指List<T>.Contains(自C#2.0起)或ArrayList.Contains(自C#1.1起),但并不直接指向数组本身。


1
我建议将名称更改为ArrayContains()以避免与Linq Contains()混淆
peter.cyc

我这样做了,尽管也有反对的理由:多态性的基本思想是对不同的数据类型使用相同的名称,尤其是考虑到Linq设置。使用不同的名称不是多态的。但是,我认为,易读性和避免误解将是赢家。
Philm

4

您只是在您的方法中缺少了一些东西:

public void PrinterSetup(string printer)
{
   if (printer == "jupiter") 
   {
      Process.Start("BLAH BLAH CODE TO ADD PRINTER VIA WINDOWS EXEC"");
   }
}

只需添加string,您就可以了。


3

不太清楚您的问题是什么,但是听起来您想要这样的事情:

    List<string> printer = new List<string>( new [] { "jupiter", "neptune", "pangea", "mercury", "sonic" } );

    if( printer.Exists( p => p.Equals( "jupiter" ) ) )
    {
        ...
    }

2

考虑使用HashSet<T>Class以获得查询性能:

此方法是O(1)操作。

HashSet<T>.Contains方法(T),MSDN

例如:

class PrinterInstaller
{
    private static readonly HashSet<string> PrinterNames = new HashSet<string>
        {
            "jupiter", "neptune", "pangea", "mercury", "sonic"
        };

    public void Setup(string printerName)
    {
        if (!PrinterNames.Contains(printerName))
        {
            throw new ArgumentException("Unknown printer name", "printerName");
        }
        // ...
    }
}

1

我现在搜索超过2小时,以找到一种很好的方式来查找列表中的重复项以及如何将其删除。这是最简单的答案:

//Copy the string array with the filtered data of the analytics db into an list
// a list should be easier to use
List<string> list_filtered_data = new List<string>(analytics_db_filtered_data);

// Get distinct elements and convert into a list again.
List<string> distinct = list_filtered_data.Distinct().ToList();

输出将如下所示:复制的元素将在名为distinct的新列表中被删除。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.