2010-03-21 91 views
2

我有一個特定類型的數組。現在我想找到滿足特定條件的條目。Array.BinarySearch滿足一定的條件

什麼是最好的辦法做到這一點的限制,我不想創建一個臨時對象來查找,而是我只想給一個搜索條件。

MyClass[] myArray; 
// fill and sort array.. 
MyClass item = Array.BinarySearch(myArray, x=>x.Name=="Joe"); // is this possible? 

也許有可能使用LINQ來解決它?

編輯: 我知道它適用於正常的集合,但我需要它爲BinarySearch工作。

回答

3

只要使用FirstOrDefault(或SingleOrDefault,如果唯一的話)。

var myItem = myArray.FirstOrDefault(x => x.Name == "Joe"); 

或者,如果你想強制BinarySearch的你知道數組進行排序

var myItem = Array.BinarySearch(myArray, 
            new MyClass { Name = "Joe" }, 
            new MyClassNameComparer()); 

其中MyClassNameComparer是IComparer<MyClass>,並比較基於name屬性。

如果你不想要任何臨時對象 - 我認爲一個常量字符串是好的,否則你會丟失 - 然後你可以使用。

var myItem = Array.BinarySearch(myArray, 
            "Joe", 
            MyClassOrStringComparer()); 

其中MyClassOrStringComparer能夠將字符串與MyClass對象進行比較(反之亦然)。

public class MyClassOrStringComparer 
{ 
    public int Compare(object a, object b) 
    { 
     if (object.Equals(a,b)) 
     { 
      return 0; 
     } 
     else if (a == null) 
     { 
      return -1; 
     } 
     else if (b == null) 
     { 
      return 1; 
     } 

     string aName = null; 
     string bName = null; 

     if (a is string) 
     { 
      aName = a; 
     } 
     else 
     { 
      aName = ((MyClass)a).Name; 
     } 

     if (b is string) 
     { 
      bName = b; 
     } 
     else 
     { 
      bName = ((MyClass)b).Name; 
     } 

     return aName.CompareTo(b.Name); 
    } 
+1

第一個是沒有binarysearch。第二個創建一個臨時對象來找到我不想創建的東西,正如我在問題中所說的那樣。 – codymanix 2010-03-21 22:21:12

+0

對不起。我誤解了你的問題,因爲不想創建一個臨時數組。我認爲你對不創建臨時對象的限制是錯誤的,因爲它使解決方案變得更容易。否則,您需要創建一個更復雜的比較器,它可以將MyClass對象與字符串進行比較。 – tvanfosson 2010-03-21 22:29:17

+0

@codymanix - note我用一個字符串/ MyClass比較器更新了我的答案,我認爲它符合您的要求 - 除了它使用臨時字符串對象。 :-) – tvanfosson 2010-03-21 22:44:25

2

不,BinarySearch不包含重載和比較<>參數。你可以使用LINQ方法來代替:

MyClass item = myArray.FirstOrDefault(x => x.Name == "Joe"); 
+5

這不是二元搜索。 – codymanix 2010-03-21 22:19:58

1

二分查找,只能當數組排序僅爲排序鍵的特定值進行搜索時使用,並且。所以這就排除了任意謂詞的使用。

0

可以利用Comparer<T>.Create()助手方法和閉合來捕捉目標值:

int i = Array.BinarySearch(myArray, null, Comparer<MyClass>.Create((item, _) => string.Compare(item.Name, "Joe", StringComparison.Ordinal))); 
if (i < 0) 
    // Complain. 
MyClass item = myArray[i]; 

這個輔助方法是可行的,因爲.NET框架4.5。

請注意,如果myArray包含滿足給定條件的多個項目,Array.BinarySearch()將返回首先找到的項目。哪個不一定是具有最小指數的項目。