2010-03-21 6 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 및 강제하려는 경우 당신이 MyClassNameComparer이 IComparer<MyClass>하고 이름 속성에 따라 비교하여 위치를 배열

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

를 정렬 것을 알고있다.

임시 개체를 원하지 않는다면 상수 문자열이 괜찮다고 가정합니다. 그렇지 않으면 손실됩니다. 그런 다음 사용할 수 있습니다.

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

+0

죄송합니다. 나는 당신의 질문을 임시 배열을 만들고 싶지 않은 것으로 잘못 읽었다. 나는 임시 객체를 생성하지 않는다는 것에 대한 당신의 제한이 솔루션을 더 쉽게 만들어주기 때문에 잘못된 것이라고 생각한다. 그렇지 않으면 MyClass 객체를 문자열과 비교할 수있는보다 복잡한 비교자를 만들어야합니다. – tvanfosson

+0

@codymanix - note 임시 문자열 개체를 사용한다는 것 외에는 사용자의 요구 사항을 충족한다고 생각되는 문자열/MyClass 비교기로 내 대답을 업데이트했습니다. :-) – tvanfosson

2

아니요, 아니요, BinarySearch에는 비교 <> 매개 변수가있는 오버로드가 포함되어 있지 않습니다.

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

이것은 binarysearch가 아닙니다. – codymanix

1

BinarySearch가 배열을 정렬하는 경우에만 사용할 수, 만 정렬 키의 특정 값을 검색 할 때 수 : 대신 LINQ의 방법을 사용할 수 있습니다. 그래서 이것은 임의의 술어의 사용을 배제합니다.

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()은 먼저 발견 한 항목을 반환합니다. 꼭 최소한의 색인을 가진 항목 일 필요는 없습니다.

관련 문제