2010-07-02 13 views
66

En SQL, puede utilizar la siguiente sintaxis:¿Hay un operador C# IN?

SELECT * 
FROM MY_TABLE 
WHERE VALUE_1 IN (1, 2, 3) 

¿Hay un equivalente en C#? El IDE parece reconocer "en" como palabra clave, pero parece que no puedo encontrar información sobre él.

Por lo tanto, es posible hacer algo como lo siguiente:

int myValue = 1; 
if (myValue in (1, 2, 3)) 
    // Do something 

En lugar de

int myValue = 1; 
if (myValue == 1 || myValue == 2 || myValue == 3) 
    // Do something 
+0

He editado esto un poco para aclarar lo que estaba tratando de comparar –

+0

cheque otra respuesta agregado por mí –

+0

Esto ya se ha preguntado varias veces sobre stackoverflow ... – chiccodoro

Respuesta

70

List.Contains() es que creo que lo que estás buscando. C# tiene inkeyword y no un operator que tiene un propósito completamente diferente al que se refiere en SQL.

Hay dos maneras en que puede usar la palabra clave in en C#. Supongamos que tiene una cadena [] o una lista en C#.

 string[] names; //assume there are some names; 

     //find all names that start with "a" 
     var results = from str in names 
         where str.StartsWith("a") 
         select str; 

     //iterate through all names in results and print 
     foreach (string name in results) 
     { 
      Console.WriteLine(name); 
     } 

En su edición, pondría su código de esta manera para hacer lo que necesita.

 int myValue = 1; 
     List<int> checkValues = new List<int> { 1, 2, 3 }; 

     if (checkValues.Contains(myValue)) 
      // Do something 
+4

La gente ve SQL y salta al instante a LINQ, pero esta sencilla función es probablemente exactamente lo que quiere –

6

No hay "en el" operador en C#, el "en" palabra clave se utiliza únicamente con "foreach (... en ...)" o "de ... en ...".

El equivalente LINQ de la consulta SQL sería:

List<int> list = new List<int> { 1, 2, 3 }; 
var query = from row in my_table 
      where list.Contains(row.value1) 
      select row; 
4

Duplicado de: LINQ to SQL in and not in

select * from table where fieldname in ('val1', 'val2') 

o

select * from table where fieldname not in (1, 2) 

El equivalente de IN y no en consultas de LINQ a SQL sería algo como esto:

List<string> validValues = new List<string>() { "val1", "val2"}; 
var qry = from item in dataContext.TableName 
      where validValues.Contains(item.FieldName) 
      select item; 

y esto:

List<int> validValues = new List<int>() { 1, 2}; 
var qry = from item in dataContext.TableName 
      where !validValues.Contains(item.FieldName) 
      select item; 
+0

Sí, lo siento, he editado mi pregunta, ya que lo que estoy preguntando no se relaciona con linq –

6

normalmente utiliza el método de una colección Contains.

myCollection.Where(p => Enumerable.Range(1,3).Contains(p)); 

Espero que ayude.

0

La palabra clave in en C# es para la instrucción foreach y para expresiones de consulta LINQ. No existe una funcionalidad equivalente al operador de SQL in en C# per se, pero LINQ ofrece una funcionalidad similar con Contains().

var list = {1, 2, 3} 
var filtered = (
    from item in items 
    where list.Contains(item) 
    select item).ToArray(). 
1

Para informado pregunta

hacer uso del interruptor de

switch (myvalue) 
{ 
    case 1: 
    case 2: 
    case 3: 
     // your code gose here 
    break; 
} 
+1

Esto es lo que terminé haciendo. Supongo que el consenso es que realmente no hay ninguna posibilidad para esto en C#. –

+5

Realmente no habría aceptado esto, porque NO es una respuesta a la pregunta del operador "in". Ver la respuesta más votados en su lugar ... – chiccodoro

+0

por supuesto funciona ... pero no tan elegante – Juri

2

Se puede escribir una extensión.Escribí hace un tiempo, para hacer código como

if(someObject.stringPropertyX.Equals("abc") || someObject.stringPropertyX.Equals("def") || ....){ 
    //do something 
    ... 
}else{ 
    //do something other... 
    .... 
} 

más fácil de leer con una extensión s.t. uno era capaz de escribir

if(someObject.stringPropertyX.In("abc", "def",...,"xyz"){ 
    //do something 
    ... 
}else{ 
    //do something other... 
    .... 
} 

Aquí está la code:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace Some.Namespace.Extenders 
{ 
    public static class StringExtender 
    { 
     /// <summary> 
     /// Evaluates whether the String is contained in AT LEAST one of the passed values (i.e. similar to the "in" SQL clause) 
     /// </summary> 
     /// <param name="thisString"></param> 
     /// <param name="values">list of strings used for comparison</param> 
     /// <returns><c>true</c> if the string is contained in AT LEAST one of the passed values</returns> 
     public static bool In(this String thisString, params string[] values) 
     { 
      foreach (string val in values) 
      { 
       if (thisString.Equals(val, StringComparison.InvariantCultureIgnoreCase)) 
        return true; 
      } 

      return false; //no occurence found 
     } 
    } 
} 

Este es el específico a mis necesidades en ese momento, pero se puede adaptar y modificar para que se ajuste más tipos diferentes.

1

No hay un operador en que busque un valor en una colección, sino que es un método de la colección, llamado Contains.

La solución más escalable es usar HashSet como colección. La comprobación de un valor en HashSet está cerca de una operación O (1), en comparación con hacerlo en un List donde se trata de una operación O (n). Eso significa que puede empaquetar una gran cantidad de valores en un HashSet y sigue siendo rápido, mientras busca un valor en un List se vuelve más lento cuantos más valores tenga.

Ejemplo:

var set = new HashSet<int>(); 
set.Add(1); 
set.Add(2); 
set.Add(3); 

var result = items.Select(i => set.Contains(i.value)); 
85

Si quería escribir .En entonces se podría crear una extensión que le permite hacer eso.

static class Extensions 
{ 

    public static bool In<T>(this T item, params T[] items) 
    { 
     if (items == null) 
      throw new ArgumentNullException("items"); 

     return items.Contains(item); 
    } 

} 


class Program 
{ 

    static void Main() 
    { 


     int myValue = 1; 

     if (myValue.In(1, 2, 3)) 
      // Do Somthing... 

     string ds = "Bob"; 

     if (ds.In("andy", "joel", "matt")) 
     // Do Someting... 
    } 
} 
+12

+1 ¿Cómo no es esta la respuesta aceptada? Este tipo quería una sintaxis similar a _'int myValue = 1; if (myValue in (1, 2, 3)) '_ Aquí puede hacer _'int myValue = 1; if (myValue.in (1, 2, 3)) '_ Solo el elemento diferente a su solicitud es el período extra. – Kayla

+0

Totalmente de acuerdo con @ WaffleStealer654, esta debería ser la respuesta aceptada – Hannish

+0

Esta es una gran respuesta. Proporciona la funcionalidad exacta solicitada y funciona igual que la instrucción SQL IN. – Rich

5

Acepto que la mejor manera de implementar el operador In es con un Método de extensión. Lo hice un poco diferente:

public static bool In(this string str, string CommaDelimintedStringSet) 
{ 
    string[] Values = CommaDelimintedStringSet.Split(new char[] { ',' }); 
    foreach (string V in Values) 
    { 
     if (str == V) 
     return true; 
    } 
    return false; 
} 

La diferencia es que usted no tiene que poner comillas alrededor de cada valor, solamente todo el conjunto de valores delimitados por comas, que es más fácil de escribir:

bool result = MyString.In("Val1,Val2,Val3"); 
+1

Solución fría. Me gusta. –

+0

Sería mejor utilizar param-arrays con esta función. Me gusta 'public static bool In (this string str, params string [] stringSet)' y llámalo como 'bool result = myString.In (" Val1 "," Val2 "," Val3 ")' –

17

Usted puede hacer esto:

var x = 99; // searched value 

if (new[] {1,2,3,99}.Contains(x)) 
{ 
    // do something 
} 
+0

Preferí esta respuesta al los más votados, ya que el objetivo de hacer IN en lugar de repetidos controles de igualdad es reducir la complejidad del código, ¡y esto es agradable, breve y simple! – MrVimes

2

para los dígitos de 0 a 9:

"123".Contains(myValue) 

Para cualquier otra materia:

"|1|2|3|".Contains("|" + myValue + "|")