Apakah ada operator C # IN?

91

Di SQL, Anda dapat menggunakan sintaks berikut:

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

Apakah ada padanan di C #? IDE tampaknya mengenali "dalam" sebagai kata kunci, tetapi saya tampaknya tidak dapat menemukan informasi apa pun tentangnya.

Jadi, mungkinkah melakukan sesuatu seperti berikut:

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

Dari pada

int myValue = 1;
if (myValue == 1 || myValue == 2 || myValue == 3)
    // Do something
Paul Michaels
sumber
Saya telah mengedit ini sedikit untuk mengklarifikasi apa yang saya coba bandingkan
Paul Michaels
periksa jawaban lain yang ditambahkan oleh saya
Pranay Rana
Ini telah ditanyakan beberapa kali di stackoverflow ...
chiccodoro
3
@chiccodoro jika pertanyaan ini telah ditanyakan sebelumnya maka tandai sebagai duplikat dan kirim jawaban dengan tautan ke pertanyaan asli, jangan tinggalkan komentar negatif
Hannish

Jawaban:

128

Jika Anda ingin menulis. Kemudian Anda dapat membuat ekstensi yang memungkinkan Anda melakukan itu.

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...
    }
}
Andy Robinson
sumber
1
Ingatlah untuk menambahkan menggunakan System.Linq;
Tanner Ornelas
In jauh lebih baik untuk dibaca daripada berisi ... Lebih mudah untuk dipahami
Konrad
85

List.Contains()adalah saya pikir apa yang Anda cari. C # memiliki in keyworddan bukan operatoryang melayani tujuan yang sama sekali berbeda dari apa yang Anda maksud di SQL.

Ada dua cara untuk menggunakan inkata kunci di C #. Asumsikan Anda memiliki string [] atau List di 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);
        }

Mengacu pada hasil edit Anda, saya akan meletakkan kode Anda seperti ini untuk melakukan apa yang Anda butuhkan.

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

        if (checkValues.Contains(myValue))
            // Do something 
ini. __curious_geek
sumber
4
Orang-orang melihat SQL dan langsung beralih ke LINQ, tetapi fungsi sederhana ini mungkin persis seperti yang dia inginkan
Bart van Heukelom
30

Kamu bisa melakukan ini:

var x = 99; // searched value

if (new[] {1,2,3,99}.Contains(x))
{
   // do something
}
JwJosefy
sumber
2
Saya lebih suka jawaban ini untuk yang terpilih lebih tinggi karena inti dari keinginan untuk melakukan IN daripada pemeriksaan kesetaraan berulang adalah untuk mengurangi kompleksitas kode, dan ini bagus dan singkat dan sederhana!
MrVimes
7

Anda biasanya menggunakan Containsmetode pengumpulan.

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

Saya harap ini membantu.

Luke yang beruntung
sumber
6

Tidak ada operator "in" di C #, kata kunci "in" hanya digunakan dengan "foreach (... in ...)" atau "from ... in ...".

LINQ yang setara dengan kueri SQL Anda adalah:

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

Duplikat dari: LINQ ke SQL dan bukan dalam

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

atau

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

Persamaan dari kueri IN dan NOT IN di LINQ ke SQL akan menjadi seperti ini:

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

dan ini:

List<int> validValues = new List<int>() { 1, 2}; 
var qry = from item in dataContext.TableName 
          where !validValues.Contains(item.FieldName) 
          select item; 
Pranay Rana
sumber
Ya - maaf, saya telah mengedit pertanyaan saya, karena apa yang saya tanyakan tidak berhubungan dengan LINQ
Paul Michaels
4

Saya setuju cara terbaik untuk menerapkan operator In adalah dengan Metode Ekstensi. Saya melakukannya sedikit berbeda:

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

Perbedaannya adalah Anda tidak perlu meletakkan tanda kutip di sekitar setiap nilai, hanya seluruh kumpulan nilai yang dipisahkan koma, yang lebih mudah untuk diketik:

bool result = MyString.In("Val1,Val2,Val3");
Chuck Bevitt
sumber
Akan lebih baik jika menggunakan param-array dengan fungsi ini. Suka public static bool In(this string str, params string[] stringSet)dan sebut sepertibool result = myString.In("Val1", "Val2", "Val3")
Manuel Hoffmann
2

Anda dapat menulis ekstensi. Saya menulis satu waktu lalu, untuk membuat kode like

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

lebih mudah dibaca dengan ekstensi yang bisa menulis

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

Ini kodenya :

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

Ini adalah yang khusus untuk kebutuhan saya saat itu, tetapi Anda dapat menyesuaikan dan memodifikasinya untuk mencocokkan lebih banyak jenis berbeda.

Juri
sumber
2

Untuk angka dari 0 sampai 9:

"123".Contains(myValue)

Untuk Barang lainnya:

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

Untuk pertanyaan Anda yang diperbarui, Anda juga bisa menggunakan pernyataan switch.

switch (myvalue)
{
   case 1:
   case 2:
   case 3: 
      // your code goes here
  break;
}
Pranay Rana
sumber
1
Inilah yang akhirnya saya lakukan. Saya kira konsensusnya adalah bahwa sebenarnya tidak ada fasilitas untuk ini di C #.
Paul Michaels
5
Saya tidak akan benar-benar menerima ini, karena ini BUKAN jawaban untuk pertanyaan operator "dalam". Lihat jawaban dengan suara terbanyak sebagai gantinya ...
chiccodoro
6
Saya tidak akan merekomendasikan pendekatan ini sama sekali! Ini tidak terukur dan memiliki kemampuan untuk membuat hidup sesama pemrogram Anda sengsara!
dekloning
3
@ decyclone: ​​Ya, Ini semua tentang pemeliharaan. kode seolah-olah programmer berikutnya yang menggantikan Anda adalah pembunuh berantai dan tahu di mana Anda tinggal.
ini. __curious_geek
Saya tidak setuju, tidak ada jawaban sebenarnya untuk pertanyaan tersebut (atau jawabannya adalah "tidak, itu tidak ada di C #") - jadi ini sepertinya alternatif yang paling dekat dengan saya. Anda juga harus ingat bahwa pertanyaan itu didasarkan pada fungsi bahasa dan bukan gaya.
Paul Michaels
1

Tidak ada operator in yang mencari nilai dalam koleksi, melainkan metode koleksi, yang disebut Contains.

Solusi paling skalabel adalah dengan menggunakan a HashSetsebagai koleksi. Memeriksa nilai dalam a HashSetmendekati operasi O (1), dibandingkan dengan melakukannya di Listtempat yang merupakan operasi O (n). Itu berarti Anda dapat mengemas banyak nilai di a HashSetdan masih cepat, sambil mencari nilai di aList semakin lambat semakin banyak nilai yang Anda miliki.

Contoh:

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

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

Umum, LINQ jauh lebih kuat:

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;
bjolfr.dll
sumber
0

Kata inkunci dalam C # adalah untuk foreachpernyataan dan untuk ekspresi kueri LINQ. Tidak ada fungsionalitas yang setara dengan inoperator SQL di C # per se, tetapi LINQ menawarkan fungsionalitas serupa dengan Contains().

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

Saya melakukan sesuatu seperti ini:

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();
BRBdot
sumber