【问题标题】:Array.BinarySearch where a certain condition is met满足特定条件的 Array.BinarySearch
【发布时间】:2010-03-21 22:10:58
【问题描述】:

我有一个特定类型的数组。现在我想找到一个满足特定条件的条目。

在我不想创建要查找的临时对象但只想给出搜索条件的限制下,首选方法是什么。

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

或许可以用LINQ来解决?

编辑: 我知道它适用于普通集合,但我需要它适用于 BinarySearch。

【问题讨论】:

    标签: c# .net linq arrays comparison


    【解决方案1】:

    只需使用 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 );
       }
    

    【讨论】:

    • 第一个不是二进制搜索。正如我在问题中所述,第二个创建了一个临时对象来查找我不想创建的对象。
    • 对不起。我将您的问题误读为不想创建临时数组。我认为您对不创建临时对象的限制是错误的,因为它使解决方案更容易。否则,您需要创建一个更复杂的比较器,可以将 MyClass 对象与字符串进行比较。
    • @codymanix -- 请注意,我已经用我认为符合您要求的字符串/MyClass 比较器更新了我的答案 -- 除了它使用临时字符串对象。 :-)
    • 这只有在myArray 使用相同的MyClassNameComparer 排序时才有效。您不能使用一个比较器对数组进行排序,而另一个比较器(给出不同的排序顺序)在该数组的二进制搜索中,因为您会得到不正确的结果。
    【解决方案2】:

    BinarySearch 只能在对数组进行排序时使用,并且只能在搜索排序键的特定值时使用。所以这排除了使用任意谓词。

    【讨论】:

      【解决方案3】:

      不,BinarySearch 不包含带有 Comparision 参数的重载。您可以改用 LINQ 方法:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-04-03
        • 1970-01-01
        • 1970-01-01
        • 2012-01-22
        • 2021-05-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多