2015-10-28 16 views
6

Tôi đã tình cờ gặp một tình huống thú vị, mà tôi không thể tìm thấy giải pháp. Giả sử tôi phải tìm chính trong một chuỗi (số xuất hiện ít nhất là n/2 + 1 lần, trong đó n là kích thước của chuỗi). Đây là triển khai thực hiện của tôi:SingleOrDefault() khi chuỗi chứa giá trị mặc định

public static int FindMajorant(IList<int> numbers) 
{ 
    return numbers 
     .GroupBy(x => x) 
     .Where(g => g.Count() >= numbers.Count/2 + 1) 
     .Select(g => g.Key) 
     .SingleOrDefault(); 
} 

Tôi đang sử dụng SingleOrDefault(), mà trả về phần tử nếu nó tìm thấy trong chuỗi hoặc giá trị mặc định cho các loại hình: trong trường hợp này, nó sẽ trở lại 0 vì nó là giá trị mặc định cho an int. Ví dụ: phương thức của tôi trả về 3 cho chuỗi sau:

List<int> sampleNumbers = new List<int>() { 2, 2, 3, 3, 2, 3, 4, 3, 3 }; 

đó là hành vi mong đợi.

Tuy nhiên, điều gì sẽ xảy ra nếu chủ thể trong chuỗi là 0 (0)? Nó sẽ trả về 0, nhưng theo cách đó, làm thế nào tôi có thể xác định xem đó là số không từ SingleOrDefault() là một giá trị mặc định, hoặc là chính? Có lẽ, tôi có thể sử dụng Single(), nhưng điều đó sẽ ném một ngoại lệ mà là khá nhiều incorrent. Tôi cũng có thể bắt ngoại lệ này, nhưng điều này có vẻ là một thực tế xấu với tôi. Vì vậy, câu hỏi của tôi là, cách ưu tiên để xử lý tình huống này là gì?

+3

Lưu ý rằng bạn có thể kéo 'numbers.Count/2 + 1' ra khỏi các truy vấn và thành một biến để tránh tính lại nó cho mỗi nhóm. – Servy

+0

@Servy không phải là 'Đếm' một thuộc tính của' IList 'vì vậy nó không thực sự được tính toán? –

+0

@MichaelMcGriff Ông đang đề cập đến các biểu hiện như một toàn thể. – arnaudoff

Trả lời

8

Sử dụng giá trị nullable trong đó null cho biết rằng không có chính, thay vì sử dụng "0" để có nghĩa là. Và đủ thuận tiện, giá trị mặc định của int?null, do đó, thay đổi duy nhất cần thiết đối với mã của bạn là nhận được chuỗi int có thể vô hiệu trước khi gọi SingleOrDefault.

public static int? FindMajorant(IList<int> numbers) 
{ 
    return numbers 
     .GroupBy(x => x) 
     .Where(g => g.Count() >= numbers.Count/2 + 1) 
     .Select(g => (int?)g.Key) 
     .SingleOrDefault(); 
} 
+0

Rất thanh lịch, cảm ơn. – arnaudoff

0

Bạn có thể chiếu kết quả vào một đối tượng gõ nói MajorantResult do đó sau đó trở về null:

public static MajorantResult FindMajorant(IList<int> numbers) 
    { 
     return numbers 
      .GroupBy(x => x) 
      .Where(g => g.Count() >= numbers.Count/2 + 1) 
      .Select(g => new MajorantResult(g.Key)) 
      .SingleOrDefault(); 
    } 

    public class MajorantResult 
    { 
     public int Key { get; } 

     public MajorantResult(int key) 
     { 
      this.Key = key; 
     } 
    } 
Các vấn đề liên quan