C#: ¿La forma más elegante de probar si int x es un elemento de un conjunto dado?
Problema: Prueba si x ∉ { 2, 3, 61, 71 }
A menudo me preguntaba si no hay una mejor manera que:
if (x != 2 && x != 3 && x != 61 && x != 71)
{
// do things
}
Y
if (!new List<int>{ 2, 3, 61, 71 }.Contains(x))
{
// do things
}
Este último parece bastante elegante, pero en realidad es un poco irritante si lo lees, especialmente debido a la inversión. Es algo feo porque en inglés decimos "x no es un elemento de ...", que es difícil de expresar en C# sin irritar la sobrecarga. Tal vez uno podría decir if (Object(x).IsElementOf(new[] { ... }))
o así?
Hmm.. alguna sugerencia? Ser ¿hay algún método estándar. Net para probar cosas así?
6 answers
Uso un método de extensión:
using System.Linq;
...
public static bool In<T>(this T item, params T[] list)
{
return list.Contains(item);
}
...
if (!x.In(2,3,61,71))
...
Puede cambiarle el nombre a IsElementOf
si prefiere este nombre...
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-22 15:14:59
Vieja pregunta, pero no he visto esta respuesta simple:
!new []{2, 3, 61, 71}.Contains(x)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-19 20:25:03
Puedes usar el siguiente método LinQ:
var list = new List<int> { 1, 2, 3, 4, 5 };
var number = 3;
if (list.Any(item => item == number))
//number is in the list
Y para la legibilidad se puede poner en un método de extensión:
public static bool IsElementOf(this int n, IEnumerable<int> list)
{
return list.Any(i => n == i);
}
//usage
if(3.IsElementOf(list)) //in the list
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-22 15:11:42
¿Qué pasa con
if(new[] { 2, 3, 61, 71 }.Except(x).FirstOrDefault() != 0)
{
...
}
O algo en esas líneas?
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-22 15:41:43
var list=CreateNewList(); //returns your list of elements
var element=GetElement(); //returns an element that might be in the list
if(list.Any(x=>x.Equals(element))
{
//do something
}
Todavía está invertido de lo que estás acostumbrado, pero es más expresivo (si la lista tiene algún valor que sea igual a elemento).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-22 15:06:15
Asumiendo que se refiere a && y no ||, puede escribir un func y usarlo a lo largo de su código. Puede acortar la nueva parte [] ya que el tipo (int) es inferido por el parámetro in del func.
Func<int, bool> IsSafe = x => !new[] { 2, 3, 61, 71 }.Contains(x);
Console.WriteLine(IsSafe(68)); // is true
Console.WriteLine(IsSafe(2)); // is false
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-22 15:46:47