检查变量是不是在临时值列表中
Posted
技术标签:
【中文标题】检查变量是不是在临时值列表中【英文标题】:Check if a variable is in an ad-hoc list of values检查变量是否在临时值列表中 【发布时间】:2013-05-27 19:11:35 【问题描述】:有没有更短的方法来写这样的东西:
if(x==1 || x==2 || x==3) // do something
我正在寻找的是这样的:
if(x.in((1,2,3)) // do something
【问题讨论】:
if(x>=1 && x<=3)
?
你的方式有什么问题吗?你有更多比较吗?因为前者(仅用于 3 次甚至 4 次比较)通常比后者更具可读性。
第一个有什么问题?它足够短,可以自我解释,并且尽可能高效。
+1 当您执行x == A || x == B || x == C || ... || x == Z
时,您要表达的是:x is in the set A, B, C, ..., Z?
,因此最清晰的语法是x in A,B,C, ..., Z
。当条件不同时,应使用||
。
【参考方案1】:
您可以使用List.Contains 方法实现此目的:
if(new []1, 2, 3.Contains(x))
//x is either 1 or 2 or 3
【讨论】:
我把这个放在同一个班里 当我运行它时,我得到“System.Array 没有实现包含”。您正在尝试将存在于 System.Collections.Generic 中的列表方法应用于存在于 System. 中的数组方法 在 .Net Core 5.x 中,这种方法似乎不起作用。不得不这样做int x = 1; if((new List<int> 1, 2, 3).Contains(x))
【参考方案2】:
public static bool In<T>(this T x, params T[] set)
return set.Contains(x);
...
if (x.In(1, 2, 3))
...
必读:MSDN Extension methods
【讨论】:
甚至可以将其更新为使用params
,这样你就会得到x.In(1, 2, 3)
之类的东西 编辑:当然,那时你可以写x.In()
,即有点傻。 (另一方面,避免了现有的IEnumerable<T>
版本,您可以传入x.In(null)
并抛出异常)
更好,你听说过params
吗?
虽然这绝对是优雅,但我个人讨厌适用于所有事物的扩展方法。 +1 还是一样的:我喜欢优雅 :)
我一直收到这个错误“扩展方法只能在非泛型非静态类中声明”
@user1854438:不,这必须在一个单独的公共类中。我已经更新了答案以包含一个链接,该链接应该让您继续使用扩展方法。【参考方案3】:
如果它在 IEnumerable<T>
中,请使用:
if (enumerable.Any(n => n == value)) //whatever
否则,这里有一个简短的扩展方法:
public static bool In<T>(this T value, params T[] input)
return input.Any(n => object.Equals(n, value));
把它放在static class
,你可以这样使用它:
if (x.In(1,2,3)) //whatever
【讨论】:
FGITW 又来了! 呃。 我认为你想要n => object.Equals(n, value)
,因为a) 可以防范null
,b) 确保非值类型有机会实现值相等。 (我认为使用Contains()
而不是Any()
会完成同样的事情。)
哦,别忘了右括号【参考方案4】:
int x = 1;
if((new List<int> 1, 2, 3).Contains(x))
【讨论】:
【参考方案5】:我完全是在猜测,如果我错了,请纠正代码:
(new int[]1,2,3).IndexOf(x)>-1
【讨论】:
【参考方案6】:您可以创建一个简单的Dictionary<TKey, TValue>
,用作该问题的Decision Table:
//Create your decision-table Dictionary
Action actionToPerform1 = () => Console.WriteLine("The number is okay");
Action actionToPerform2 = () => Console.WriteLine("The number is not okay");
var decisionTable = new Dictionary<int, Action>
1, actionToPerform1,
2, actionToPerform1,
3, actionToPerform1,
4, actionToPerform2,
5, actionToPerform2,
6, actionToPerform2
;
//According to the given number, the right *Action* will be called.
int theNumberToTest = 3;
decisionTable[theNumberToTest](); //actionToPerform1 will be called in that case.
一旦你初始化了你的Dictionary
,剩下要做的就是:
decisionTable[theNumberToTest]();
【讨论】:
这是我见过的最小的过度设计的单个单元之一。鉴于上下文。 这是最干净、最快的方法之一。这就是执行if
条件所需要做的所有事情:decisionTable[theNumberToTest]();
我喜欢人们使用 O(?) 来尝试证明某事比另一个“更快”。它闻起来有新鲜的肉味和一丝薄荷味。
如果你只做一次测试,那么这很容易比Contains
慢——构建字典是 O(n),就像构建和扫描列表一样。
@Ryan Dictionary
只能构建一次。【参考方案7】:
这个答案指的是未来可能的 C# 版本;-) 如果您考虑切换到 Visual Basic,或者如果 Microsoft 最终决定将 Select Case 语句引入 C#,它看起来像这样:
Select Case X
Case 1, 2, 3
...
End Select
【讨论】:
以上是关于检查变量是不是在临时值列表中的主要内容,如果未能解决你的问题,请参考以下文章