2010-05-26 43 views
20

Tôi đã hai mảng nhưSo sánh Mảng sử dụng LINQ trong C#

string[] a = { "a", "b", "c" }; 
string[] b = { "a", "b", "c" }; 

Tôi cần phải so sánh hai mảng sử dụng LINQ.

So sánh sẽ chỉ diễn ra nếu cả hai mảng có cùng kích thước. Dữ liệu có thể theo bất kỳ thứ tự nào và vẫn trả về true nếu tất cả các giá trị của [] và tất cả các giá trị của b [] đều giống nhau.

+0

từ x trong một từ y trong b trong đó x == y chọn x == y nhưng nó không chính xác ... có thể không lưu trữ trong biến Boolean –

+0

Mỗi mảng có giá trị duy nhất không? Khi bạn xem xét hai mảng giống nhau? nếu chúng có cùng yếu tố? các yếu tố giống nhau trong cùng một thứ tự? –

+0

Bạn đang tìm kiếm một câu trả lời bool duy nhất nếu hai là hoàn toàn giống nhau hoặc bạn đang tìm kiếm một kiểm tra để xem nếu mỗi phần tử là giống như đối tác của nó. –

Trả lời

27
string[] a = { "a", "b" }; 
string[] b = { "a", "b" }; 

return (a.Length == b.Length && a.Intersect(b).Count() == a.Length); 

Sau một số thử nghiệm hiệu suất:

  • Hơn 10.000 chuỗi nhỏ - 5ms
  • Hơn 100.000 chuỗi nhỏ - 99ms
  • Hơn 1.000.000 dây nhỏ - Avg. 601ms
  • Trên 100.000 ~ 500 chuỗi ký tự - 190ms
+1

nhưng tôi không nghĩ rằng hiệu suất là ok. giao lộ không hoạt động giá rẻ – Andrey

+0

@Andrey - Nó cũng phụ thuộc vào kích thước của danh sách. –

+4

Cú pháp, tôi muốn nói 'return (a.Length == b.Length && a.Intersect (b) .Count() == a.Length)', nhưng đó chỉ là tôi. – ZombieSheep

19

Không chắc chắn về hiệu suất, nhưng điều này có vẻ hiệu quả.

string[] a = { "a", "b", "c" }; 
string[] b = { "a", "b", "c" }; 

bool result = a.SequenceEqual(b); 
Assert.AreEqual(true, result); 

Tuy nhiên, đơn đặt hàng không độc lập nên không đáp ứng yêu cầu của OP.

string[] a = { "a", "b", "c" }; 
string[] b = { "a", "c", "b" }; 

bool result = a.SequenceEqual(b); 
Assert.AreEqual(false, result); 
+2

Ý của bạn là gì, "đó là đơn đặt hàng độc lập"? SequenceEqual KHÔNG phải là đơn độc. Trong mẫu mã thứ hai của bạn, nó sẽ trả về false –

+0

Bạn là chính xác. Đã chỉnh sửa. –

+0

Không downvoting, nhưng điều này không trả lời câu hỏi. Theo op: 'không theo thứ tự ... nhưng hai mảng phải có kích thước bằng nhau ' –

4

nếu tự không quan trọng hoặc có thể là bản sao thì có lẽ:

public static class IEnumerableExtensions 
{ 
    public static bool HasSameContentsAs<T>(this ICollection<T> source, 
              ICollection<T> other) 
    { 
     if (source.Count != other.Count) 
     { 
      return false; 
     } 
     var s = source 
      .GroupBy(x => x) 
      .ToDictionary(x => x.Key, x => x.Count()); 
     var o = other 
      .GroupBy(x => x) 
      .ToDictionary(x => x.Key, x => x.Count()); 
     int count; 
     return s.Count == o.Count && 
       s.All(x => o.TryGetValue(x.Key, out count) && 
          count == x.Value); 
    } 
} 

sử dụng:

string[] a = { "a", "b", "c" }; 
string[] b = { "c", "a", "b" }; 

bool containSame = a.HasSameContentsAs(b); 

một số trường hợp sử dụng:

  • khác nhau độ dài (mong đợi sai)

    string[] a = { "a", "b", "c" }; 
    string[] b = { "b", "c" }; 
    
  • thứ tự khác nhau (hy vọng đúng)

    string[] a = { "a", "b", "c" }; 
    string[] b = { "b", "c", "a" }; 
    

cũng hoạt động nếu đầu vào có thể chứa mục trùng lặp, mặc dù nó không phải là rõ ràng từ câu hỏi liệu đặc trưng đó là mong muốn hay không , hãy xem xét:

  • các mục trùng lặp có cùng số lượng (mong đợi là đúng)

    string[] a = { "a", "b", "b", "c" }; 
    string[] b = { "a", "b", "c", "b" }; 
    
  • mục lặp lại với số lượng khác nhau (hy vọng sai)

    string[] a = { "a", "b", "b", "b", "c" }; 
    string[] b = { "a", "b", "c", "b", "c" }; 
    
+0

Nếu bạn so sánh kích thước của chúng trước tiên, bạn sẽ cần cả hai chứaTất cả hoạt động? –

+1

@Scott, Có. Xem xét a = {"a", "b", "c"}; b = {"c", "a". "a"}; cùng chiều dài nhưng các mục duy nhất trong b là một tập con của những người trong một – Handcraftsman

5

Tôi nghĩ rằng đây sẽ luôn là một O (n log n) hoạt động, vì vậy tôi muốn chỉ là loại cả hai mảng và so sánh chúng ví dụ sử dụng SequenceEqual.

3
IDictionary<int, object> a = new Dictionary<int, object>(); 
IDictionary<int, object> b = new Dictionary<int, object>(); 
a.Add(1, "1"); 
a.Add(2, 2); 
a.Add(3, "3"); 

b.Add(3, "3"); 
b.Add(1, "1"); 
b.Add(2, 2); 

Console.WriteLine(a.All(i => b.Contains(i)) && b.All(i => a.Contains(i))); 
2

này hoạt động một cách chính xác với bản sao và kiểm tra từng yếu tố

a.Length == b.Length && !a.Where((t, i) => t != b[i]).Any()