检查值是不是在数组中(C#)
Posted
技术标签:
【中文标题】检查值是不是在数组中(C#)【英文标题】:Check if a value is in an array (C#)检查值是否在数组中(C#) 【发布时间】:2012-10-26 18:50:44 【问题描述】:如何在 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");
如何以 C# 可以识别的方式格式化 if (printer == "jupiter")
?
【问题讨论】:
尝试给你的参数名称一个类型(字符串),就可以了。 我对这个问题有点困惑。您是在问如何检查一个值是否在数组中,或者如何在 C# 中进行字符串比较?如果是后者,您将使用printer.Equals("jupiter")
。如果是前者,请使用linq
和printer.Contains("jupiter")
@newfurniturey 相当...问题很混乱,示例代码与标题不匹配,因此答案也很混乱;为什么像这样的废话会被赞成,这超出了我的理解。而且没有必要做printer.Equals("jupiter")
... OP 的代码if (printer == "jupiter")
工作得很好...只要printer
被声明为一个字符串,正如Skeet 所指出的那样。
【参考方案1】:
添加必要的命名空间
using System.Linq;
那么就可以使用linqContains()
方法
string[] printer = "jupiter", "neptune", "pangea", "mercury", "sonic";
if(printer.Contains("jupiter"))
Process.Start("BLAH BLAH CODE TO ADD PRINTER VIA WINDOWS EXEC"");
【讨论】:
@0A0D。这个答案是我认为最简单/最短且众所周知的方法来实现同样的事情(How do I check if a value is in an array in C#?
)并且效率也是最好的。没有循环没有额外的方法。只是一个命名空间是额外的,这并不是什么大事。
@Sami:Linq 在内部使用循环。
@0A0D Sam 可能指的是书面代码,而不是编译指令。 Linq 在内部使用循环和方法,但从编码人员的角度来看,所有这些都是隐藏的,不需要担心。
正确@0A0D。我的意思是编码器/开发人员不需要正确循环。从数组中检查当然需要一个循环:)
这当然简单且值得推荐。如果您无权访问 Linq,或者不想使用 Linq,则可以依赖数组的一些 显式接口实现。从 .NET 1.1 开始,我们有了 ((IList)printer).Contains("Jupiter")
,它是非泛型的(可能是框值类型等),甚至适用于多维数组。从 .NET 2.0 开始,我们有了更神奇的((IList<string>)printer).Contains("Jupiter")
,它更安全。 Linq 方法是 .NET 3.5 中的新方法。【参考方案2】:
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); // true
Console.WriteLine(b); // false
Console.WriteLine(c); // true
Console.WriteLine(d); // false
【讨论】:
这应该是公认的答案。如果您使用数组,则并非完全不可能,该性能确实很重要。在这种情况下,Linq 往往是错误的选择。 请注意,“并非完全不可能”并不意味着“完全可能”。在这种情况下,阵列大小很可能会非常小,并且任何性能下降都将完全无法检测到。 IMO 下面使用 Linq 的单行答案是最清晰的实现。【参考方案3】:在文件顶部添加using System.Linq;
。然后你可以这样做:
if ((new [] "foo", "bar", "baaz").Contains("bar"))
【讨论】:
这是一个普遍的例子——你能提供一个更符合问题的例子吗? 这可能是一个普遍的例子,但这正是我想要的。【参考方案4】: public static bool Contains(Array a, object val)
return Array.IndexOf(a, val) != -1;
【讨论】:
我喜欢这个。但是,如果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;
我喜欢这个,但只是因为它没有 Linq 并且它确认 IndexOf 是唯一要使用的left。【参考方案5】:
这样的?
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"");
【讨论】:
【参考方案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 及更高版本)来添加语法糖,以获得与不包括 Linq 的所有数组的字符串相同/相似的“.Contains”:
// 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 起),但不直接指向数组本身。
【讨论】:
我建议将名称更改为 ArrayContains() 以避免与 Linq Contains() 混淆 我已经这样做了,尽管也有人反对:多态性的基本思想是为不同的数据类型使用相同的名称,尤其是考虑到 Linq 设置。使用不同的名称不是多态。但我认为,可读性和避免误解会赢,所以,是的。【参考方案7】:你只是在你的方法中遗漏了一些东西:
public void PrinterSetup(string printer)
if (printer == "jupiter")
Process.Start("BLAH BLAH CODE TO ADD PRINTER VIA WINDOWS EXEC"");
只需添加string
即可。
【讨论】:
【参考方案8】:不是很清楚你的问题是什么,但听起来你想要这样的东西:
List<string> printer = new List<string>( new [] "jupiter", "neptune", "pangea", "mercury", "sonic" );
if( printer.Exists( p => p.Equals( "jupiter" ) ) )
...
【讨论】:
【参考方案9】:为了查找性能考虑使用HashSet<T>
Class:
此方法是 O(1) 操作。
——
HashSet<T>.Contains
Method (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");
// ...
【讨论】:
【参考方案10】:我现在搜索了超过 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 的新列表中删除!
【讨论】:
以上是关于检查值是不是在数组中(C#)的主要内容,如果未能解决你的问题,请参考以下文章