#c#
#c#
Вопрос:
Вместо чего-то подобного:
switch (id) {
case 2:
case 5:
case 11:
case 15:
...
}
Есть ли краткий способ проверить, равна ли переменная int любому из ряда целых чисел? Может быть, что-то вроде if (id == {2|5|11|15}) ...
?
Ответ №1:
Вы могли бы поместить все целые числа в HashSet и выполнить contains .
Hashset<int> ids = new HashSet<int>() {...initialize...};
if(ids.Contains(id)){
...
}
Комментарии:
1. Спасибо… никогда не использовал Hashset. После небольшого поиска оказывается, что они ПОТРЯСАЮЩИЕ (потому что они быстрые). vcskicks.com/hashset.php
2. В случае, о котором вы говорите, с проверкой определенных значений, вам пришлось бы провести некоторое тестирование по сравнению с инструкцией switch в отношении производительности. Они должны быть относительно близки, но HashSet, вероятно, немного медленнее. Также будьте осторожны с проблемой дня рождения. Эрик Липперт прекрасно объясняет это здесь: blogs.msdn.com/b/ericlippert/archive/2010/03/22 /…
3. Спасибо… в этом случае я просто хотел проверить, был ли данный int тем, который содержался в этих нескольких числах. Она не будет масштабироваться больше. Спасибо, что привели меня к HashSets, очень ценю.
4. @Chad, @Craig: кстати, компилятор сам сгенерирует хэш-таблицу для кодирования switch, если он считает, что это сделает код switch быстрее и меньше.
5. Спасибо, Эрик, это отличное понимание этого; Я действительно ценю ваше дополнение к этой теме.
Ответ №2:
if((new List<int> { 2, 5, 11, 15}).Contains(id))
Но вы, вероятно, не хотите каждый раз создавать новый List
экземпляр, поэтому было бы лучше создать его в конструкторе вашего класса.
Комментарии:
1. Может быть, если бы это было так
if((new HashSet<int> {2,5,11,15}).Contains(id)){...}
, это было бы производительно? vcskicks.com/hashset.php2. С этими несколькими элементами не будет никакой разницы в производительности. Проблема заключается в создании объекта, а не в поиске.
3. Хороший момент … lol, с этими несколькими элементами проблем не будет… думаю, я снова застрял в режиме «чистой производительности» … спасибо.
Ответ №3:
Вы могли бы попробовать:
List<int> ints = new List<int> {2, 5, 11, 15};
if (ints.Contains(id))
{
}
Хотя это может быть медленнее, чем выполнение переключения.
Однако у него есть то преимущество, что (при условии, что вы инициализируете список из данных) вы можете использовать это для проверки любого списка целочисленных значений и не ограничены жестко закодированными значениями.
Комментарии:
1. Спасибо, это сработало бы. Мне нравится Hashset немного больше, потому что он работает лучше, чем
List<>
. Тем не менее, я ценю ваш ответ.2. @Chad — без проблем. Однако моя точка зрения об отсутствии жестко закодированных значений все еще актуальна….
Ответ №4:
Если ваша цель — быть кратким.
//
(new []{2, 5, 11, 15}).Contains(id)
//
Если вы хотите работать быстро, вероятно, придерживайтесь switch.
Хотя, думаю, мне нравится HashSet.
Комментарии:
1. Если бы они были отсортированы, вы могли бы также сделать это:
Array.BinarySearch(new[] { ... }, id) != -1
Ответ №5:
Возможно, решение с использованием LINQ:
List<int> ints = new List<int> {2, 5, 11, 15};
void Search(int s) {
int result = ints.Where(x => x == s).FirstOrDefault();
}
Ответ №6:
Вы можете сделать что-то вроде этого:
bool exist = List.Init(6, 8, 2, 9, 12).Contains(8);
foreach (int i in List.Init(6, 8, 2, 9, 12))
{
Console.WriteLine(i.ToString());
}
public class List : IEnumerable<int>
{
private int[] _values;
public List(params int[] values)
{
_values = values;
}
public static List Init(params int[] values)
{
return new List(values);
}
public IEnumerator<int> GetEnumerator()
{
foreach (int value in _values)
{
yield return value;
}
}
public bool Contains(int value)
{
return Array.IndexOf(_values, value) > -1;
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}