Có toán tử C # IN không?


89

Trong SQL, bạn có thể sử dụng cú pháp sau:

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

Có tương đương trong C # không? IDE dường như nhận ra "in" là một từ khóa, nhưng tôi dường như không thể tìm thấy bất kỳ thông tin nào về nó.

Vì vậy, có thể làm điều gì đó như sau:

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

Thay vì

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

Tôi đã chỉnh sửa một chút này để làm rõ những gì tôi đã cố gắng để so sánh
Paul Michaels

kiểm tra một câu trả lời bổ sung bởi tôi
Pranay Rana

Này đã được hỏi nhiều lần trên stackoverflow ...
chiccodoro

3
@chiccodoro nếu câu hỏi này đã được hỏi trước cờ sau đó nó như là một bản sao và gửi câu trả lời với các liên kết đến các câu hỏi ban đầu, không chỉ để lại nhận xét tiêu cực
Hannish

Câu trả lời:


125

Nếu bạn muốn viết .In thì bạn có thể tạo một tiện ích mở rộng cho phép bạn làm điều đó.

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
Chỉ cần nhớ thêm bằng cách sử dụng System.Linq;
Tanner Ornelas

In là tốt hơn rất nhiều để đọc hơn chứa ... Dễ hiểu
Konrad

84

List.Contains()là tôi nghĩ những gì bạn đang tìm kiếm. C # có in keywordvà không operatorcó phục vụ mục đích hoàn toàn khác với những gì bạn đang đề cập trong SQL.

Có hai cách bạn có thể sử dụng intừ khóa trong C #. Giả sử bạn có một chuỗi [] hoặc Danh sách trong 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);
        }

Đề cập đến bản chỉnh sửa của bạn, tôi sẽ đặt mã của bạn theo cách này để thực hiện những gì bạn cần.

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

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

4
Mọi người nhìn thấy SQL và ngay lập tức nhảy đến LINQ, nhưng chức năng đơn giản này có lẽ là chính xác những gì anh ta muốn
Bart van Heukelom

29

Bạn có thể làm được việc này:

var x = 99; // searched value

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

2
Tôi thích câu trả lời này cho những người được bình chọn cao hơn vì toàn bộ điểm của việc muốn thực hiện IN thay vì kiểm tra bình đẳng lặp đi lặp lại là để giảm độ phức tạp của mã, và điều này rất hay, ngắn gọn và đơn giản!
MrVimes

1
Xin cảm ơn @MrVimes!
JwJosefy vào

7

Bạn thường sử dụng Containsphương pháp tập hợp.

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

Tôi hy vọng nó sẽ giúp.


6

Không có toán tử "in" trong C #, từ khóa "in" chỉ được sử dụng với "foreach (... in ...)" hoặc "from ... in ...".

LINQ tương đương với truy vấn SQL của bạn sẽ là:

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

4

Bản sao của: LINQ to SQL trong và không trong

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

hoặc là

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

Tương đương với truy vấn IN và NOT IN trong LINQ to SQL sẽ giống như sau:

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

và điều này:

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

Có - xin lỗi, tôi đã chỉnh sửa câu hỏi của tôi, như những gì tôi yêu cầu không liên quan đến LINQ
Paul Michaels

4

Tôi đồng ý rằng cách tốt nhất để triển khai toán tử Trong là với Phương pháp mở rộng. Tôi đã làm điều đó hơi khác một chút:

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

Sự khác biệt là bạn không phải đặt dấu ngoặc kép xung quanh mỗi giá trị, chỉ đặt toàn bộ tập hợp các giá trị được phân tách bằng dấu phẩy, dễ nhập hơn:

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

Sẽ tốt hơn nếu sử dụng mảng param với chức năng này. Giống như public static bool In(this string str, params string[] stringSet)và gọi nó như thếbool result = myString.In("Val1", "Val2", "Val3")
Manuel Hoffmann

2

Bạn có thể viết một phần mở rộng. Tôi đã viết một lần trước đây, để tạo mã như

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

dễ đọc hơn với một mục mở rộng mà người ta có thể viết

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

Đây là :

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

Đây là cái cụ thể cho nhu cầu của tôi tại thời điểm đó, nhưng bạn có thể điều chỉnh và sửa đổi nó để phù hợp với nhiều loại khác nhau hơn.


2

Đối với các chữ số từ 0 đến 9:

"123".Contains(myValue)

Đối với bất kỳ Nội dung nào khác:

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

2

Đối với câu hỏi cập nhật của bạn, bạn cũng có thể sử dụng câu lệnh chuyển đổi.

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

1
Đây là những gì tôi đã kết thúc. Tôi cho rằng sự đồng thuận là thực sự không có bất kỳ cơ sở nào cho điều này trong C #.
Paul Michaels

5
Tôi thực sự sẽ không chấp nhận điều này, bởi vì nó KHÔNG phải là câu trả lời cho câu hỏi về toán tử "trong". Xem top-bình chọn câu trả lời thay vì ...
chiccodoro

6
Tôi không khuyến khích cách tiếp cận này ở tất cả! Nó không thể mở rộng và có khả năng làm cho cuộc sống của các lập trình viên đồng nghiệp của bạn trở nên khốn khổ!
decyclone

3
@decyclone: ​​Vâng, Tất cả là về khả năng bảo trì. mã như thể lập trình viên tiếp theo thay thế bạn là một kẻ giết người hàng loạt và biết bạn sống ở đâu.
cái này. __curious_geek

Tôi không đồng ý, không có câu trả lời thực sự cho câu hỏi (hoặc câu trả lời là "không, không tồn tại trong C #") - vì vậy đây có vẻ là sự thay thế gần nhất với tôi. Bạn cũng phải nhớ rằng câu hỏi dựa trên chức năng ngôn ngữ chứ không phải phong cách.
Paul Michaels

1

Không có toán tử nào tìm kiếm giá trị trong tập hợp, thay vào đó là một phương thức của tập hợp, được gọi Contains.

Giải pháp có thể mở rộng nhất là sử dụng a HashSetlàm bộ sưu tập. Kiểm tra một giá trị trong a HashSetgần giống với một phép toán O (1), so với việc thực hiện nó trong một Listphép toán O (n). Điều đó có nghĩa là bạn có thể đóng gói nhiều giá trị trong a HashSetvà nó vẫn nhanh, trong khi tìm kiếm một giá trị trong a Listcàng chậm thì bạn càng có nhiều giá trị.

Thí dụ:

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

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

1

Cách phổ biến, LINQ mạnh mẽ hơn:

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

Các intừ khóa trong C # là để foreachtuyên bố và cho các biểu thức truy vấn LINQ. Không có chức năng nào tương đương với intoán tử SQL trong C #, nhưng LINQ cung cấp chức năng tương tự với Contains().

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

0

Tôi làm một cái gì đó như thế này:

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();
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.