Gibt es einen C # IN-Operator?


88

In SQL können Sie die folgende Syntax verwenden:

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

Gibt es ein Äquivalent in C #? Die IDE scheint "in" als Schlüsselwort zu erkennen, aber ich kann anscheinend keine Informationen dazu finden.

Ist es also möglich, Folgendes zu tun:

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

Anstatt

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

Ich habe dies ein wenig bearbeitet, um zu verdeutlichen, was ich zu vergleichen versuchte
Paul Michaels

Überprüfen Sie eine andere Antwort von mir hinzugefügt
Pranay Rana

Dies wurde bereits mehrmals auf Stackoverflow gefragt ...
Chiccodoro

3
@chiccodoro Wenn diese Frage schon einmal gestellt wurde, kennzeichnen Sie sie als Duplikat und posten Sie eine Antwort mit dem Link zur ursprünglichen Frage. Hinterlassen Sie nicht nur einen negativen Kommentar
Hannish

Antworten:


124

Wenn Sie .In schreiben möchten, können Sie eine Erweiterung erstellen, mit der Sie dies tun können.

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...
    }
}

1
Denken Sie daran, mit System.Linq hinzuzufügen.
Tanner Ornelas

In ist so viel besser zu lesen als enthält ... Einfacher zu verstehen
Konrad

84

List.Contains()ist ich denke was du suchst. C # hat in keywordund nicht einen operator, der einem völlig anderen Zweck dient als das, worauf Sie sich in SQL beziehen.

Es gibt zwei Möglichkeiten, wie Sie inSchlüsselwörter in C # verwenden können. Angenommen, Sie haben eine Zeichenfolge [] oder Liste in 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);
        }

In Bezug auf Ihre Bearbeitung würde ich Ihren Code so einfügen, dass Sie das tun, was Sie brauchen.

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

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

4
Die Leute sehen SQL und springen sofort zu LINQ, aber diese einfache Funktion ist wahrscheinlich genau das, was er will
Bart van Heukelom

29

Du kannst das:

var x = 99; // searched value

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

2
Ich habe diese Antwort den höher bewerteten vorgezogen, da der Sinn von IN anstelle von wiederholten Gleichheitsprüfungen darin besteht, die Codekomplexität zu reduzieren, und das ist nett und kurz und einfach!
MrVimes

1
Vielen Dank, dass Sie @MrVimes!
JwJosefy

7

Normalerweise verwenden Sie die ContainsMethode einer Sammlung.

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

Ich hoffe, es hilft.


6

In C # gibt es keinen "in" -Operator. Das Schlüsselwort "in" wird nur mit "foreach (... in ...)" oder "from ... in ..." verwendet.

Das LINQ-Äquivalent Ihrer SQL-Abfrage wäre:

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

4

Duplikat von: LINQ to SQL in und nicht in

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

oder

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

Das Äquivalent von IN- und NOT IN-Abfragen in LINQ zu SQL wäre ungefähr so:

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

und das:

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

Ja - Entschuldigung, ich habe meine Frage bearbeitet, da sich das, was ich frage, nicht auf linq bezieht
Paul Michaels

4

Ich bin damit einverstanden, dass der In-Operator am besten mit einer Erweiterungsmethode implementiert werden kann. Ich habe es etwas anders gemacht:

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;
}

Der Unterschied besteht darin, dass Sie nicht jeden Wert in Anführungszeichen setzen müssen, sondern nur den gesamten Satz von durch Kommas getrennten Werten, was einfacher einzugeben ist:

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

Es wäre besser, Parameter-Arrays mit dieser Funktion zu verwenden. Like public static bool In(this string str, params string[] stringSet)und nenne es wiebool result = myString.In("Val1", "Val2", "Val3")
Manuel Hoffmann

2

Sie können eine Erweiterung schreiben. Ich habe vor einmal geschrieben, um Code wie zu machen

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

besser lesbar mit einer Erweiterung, die man schreiben konnte

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

Hier ist der 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
        }
    }
}

Dies ist diejenige, die für meine damaligen Bedürfnisse spezifisch ist, aber Sie können sie anpassen und modifizieren, um sie an verschiedene Typen anzupassen.


2

Für Ziffern von 0 bis 9:

"123".Contains(myValue)

Für alle anderen Sachen:

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

2

Für Ihre aktualisierte Frage können Sie auch eine switch-Anweisung verwenden.

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

1
Das habe ich letztendlich getan. Ich nehme an, der Konsens ist, dass es in C # keine Möglichkeit dafür gibt.
Paul Michaels

5
Ich hätte das nicht wirklich akzeptiert, da es KEINE Antwort auf die Frage des "in" -Operators ist. Sehen Sie stattdessen die am besten
gewählte

6
Ich würde diesen Ansatz überhaupt nicht empfehlen! Es ist nicht skalierbar und kann das Leben Ihrer Programmierkollegen miserabel machen!
Decyclone

3
@decyclone: ​​Ja, es geht nur um Wartbarkeit. Code, als ob der nächste Programmierer, der Sie ersetzt, ein Serienmörder ist und weiß, wo Sie leben.
das. __curious_geek

Ich bin anderer Meinung, es gab keine tatsächliche Antwort auf die Frage (oder die Antwort war "Nein, das gibt es in C # nicht") - daher schien mir dies die naheliegendste Alternative zu sein. Sie müssen auch berücksichtigen, dass die Frage auf Sprachfunktionalität und nicht auf Stil beruhte.
Paul Michaels

1

Es gibt keinen in-Operator, der nach einem Wert in einer Sammlung sucht, sondern eine Methode der Sammlung, die aufgerufen wird Contains.

Die skalierbarste Lösung ist die Verwendung von a HashSetals Sammlung. Das Überprüfen auf einen Wert in a HashSetliegt nahe an einer O (1) -Operation im Vergleich zu Listeiner O (n) -Operation. Das bedeutet, dass Sie viele Werte in a packen können HashSetund es immer noch schnell ist, während die Suche nach einem Wert in a Listlangsamer wird, je mehr Werte Sie haben.

Beispiel:

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

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

1

Allgemein, LINQ viel leistungsfähiger:

var list = new List<string> { "Tomato", "Orange", "Mango"};
var query = from i in my_table
            from v in list
            where i.Name.StartsWith(v)
            select i;

0

Das inSchlüsselwort in C # steht für die foreachAnweisung und für LINQ-Abfrageausdrücke. Es gibt keine Funktionalität, die dem SQL- inOperator in C # per se entspricht, aber LINQ bietet ähnliche Funktionen mit Contains().

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

0

Ich mache so etwas:

var shippingAddress = checkoutContext.Addresses.Where(a => (new HashSet<AddressType> { AddressType.SHIPPING_ONLY, AddressType.BILLING_AND_SHIPPING }).Contains(a.AddressType) && a.Id == long.Parse(orderDto.ShippingAddressId)).FirstOrDefault();
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.