2010-03-21 89 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()将返回首先找到的项目。哪个不一定是具有最小指数的项目。