2011-01-06 5 views
4

저는 람다 표현을 처음 접했고 이해가 안되는 부분을 만났습니다.누군가이 람다 정렬식이 작동하지 않는 이유를 말해 줄 수 있습니까?

class MyListItem 
{ 
    string date; //date in the format "2010-12-05" 
    int Hour; //hour of day as an int 

} 

내가 어떤 날짜와 시간을 나타내는, 이러한 개체의 목록을 가지고 :

나는 물체과 같이 있습니다.

나는 날짜와 시간에 의해이 목록을 정렬 할, 그래서 나는 이것을 시도 :

List<MyListItem> myList = new List<MyListItem>(); 

myList = getsomedata(); //populate list 

myList.Sort((a, b) => (a.date + a.Hour.ToString()).CompareTo(b.date + b.Hour.ToString())); 

와 그 종류의 작품. 문제는 시간이 INT는 것을, 그래서 그렇게 같은 종류의 결과로, 때로는 없습니다 2 자리의 :

2010-12-05 1 
2010-12-05 2 
2010-12-05 10 
2010-12-05 11 
2010-12-05 12 
2010-12-05 13 
2010-12-05 21 
2010-12-05 22 

그래서 나는 형식을 시도 :

2010-12-05 1 
2010-12-05 10 
2010-12-05 11 
2010-12-05 12 
2010-12-05 13 
2010-12-05 2 
2010-12-05 21 
2010-12-05 22 

내가 좋아하는이 원하는 람다에서 함께 구문 분석하기 전에 0을 더하는 문자열 :

ret.Sort((a, b) => (a.date + a.Hour.ToString("00")).CompareTo(b.date + b.Hour.ToString("00"))); 

그러나 컴파일되지 않습니다. 그것은 나를 알려줍니다 :

Cannot convert lambda expression to type 'Systems.Collections.Generic.IComparer<MyListItem>' because it is not a delegate type. 

허? 이 상황에서 일반 .ToString() (형식 문자열 없음)과 .ToString ("00") 사이에 다른 점은 무엇입니까?

또한이 방법을 얻는 방법에 대한 제안 사항이 있으십니까?

+0

'ret'의 유형은 무엇입니까? 'List '을 만들면 두 번째 정렬 루틴과 관련된 컴파일 문제가 발생하지 않습니다. 재현성을 위해 어떤 버전의 컴파일러와 프레임 워크를 사용하고 있습니까? – Ani

+0

이상한 점은 컴파일 오류가 발생하지 않는다는 것입니다. ret는 List ()입니다 (myList가 있어야하며 잘라 내기 및 붙여 넣기 오류가 발생 했음). 나는 vs2010, .net 4.0을 사용하고있다. – BDW

답변

0

도움을 주신 모든 분들께 감사드립니다.

class MyListItem 
{ 
    string date; //date in the format "2010-12-05" 
    int? Hour; //hour of day as an int 

} 

내가 사용하고 실제 클래스는 내가 준 예보다 훨씬 큰 생성 된 클래스는 다음과 같습니다 그것이 나오는 것에 따라, 문제는 원래 클래스에서, 시간이 있었다 같은, 널 (NULL)이었다 여기에 - 나는 물건을 명확하게하기 위해 그것을 단축하려고 노력했고, 관련된 일부를 떠나 버렸다.

Null 허용 INT 작품의 값을 사용하여 정렬을 변경

:

myList.Sort((a, b) => (a.date + a.Hour.Value.ToString("00")).CompareTo(b.date + b.Hour.Value.ToString("00"))); 

오류 메시지

가 큰 도움이되지 못했습니다 만, 모두가 예 내가 그것을 추적 할 수 일하고있다.

2

이유는 그것이 순서대로 정렬되지 않고 문자열로 있기 때문입니다. 비교자를 만들어 날짜를 비교해야합니다. 정렬로보기 - 1로 시작하는 것이 2로 시작하는 것으로 시작하기 때문에 1, 11, 111, 1111, 2, 22, 222, 222, 3, 33, 333 등이됩니다.

결과 문자열을 날짜로 변환하여 수정해야합니다.

DateTime.ParseExact(a.date + hour.ToString("00"), "yyyy-MM-dd HH", CultureInfo.InvariantCulture) 

ToString()으로 인한 예외와 관련된 컴파일 문제를 피할 수 있어야합니다. 나는 PC에 아니에요

+0

컴파일 문제와 관련하여 어떤 영향이 있습니까? – Ani

+1

@Ani :이 대답은 OP 문제를 해결할 수있는 더 좋은 방법을 제안한다고 생각합니다. – VoodooChild

+1

날짜는 "있는 그대로"정렬 할 수 있습니다. - "yyyy mm dd"는 구문 분석 할 필요없이 정렬 할 수 있습니다. OP는 * 이미 * 문자열로 유효하게 정렬 할 수있는 방법으로 시간을 처리하기위한 조치를 취하고 있습니다. ... –

5

그래서 나는 처음 설명 할 수 없다,하지만 난 그것을 회피 것 : 등

ret.Sort((a,b) => { 
    int result = string.Compare(a.date,b.date); 
    if(result==0) result = a.hour.CompareTo(b.hour); 
    return result; 
}); 

적은 문자열 작품, 아니 파싱 오버 헤드;)

1

그것을 날짜가 String 형식으로 비교되기 때문입니다.

ret.Sort((a, b) => (DateTime.Parse(a.date + " " +a.Hour.ToString("00") 
+ ":00:00").CompareTo(DateTime.Parse(b.date + " " + b.Hour.ToString("00") + ":00:00"))); 
+0

"yyyy mm dd hh "등은 * 괜찮습니다 * 문자열로 정렬합니다. –

0

당신은 미친 얻을 수있는 기존 필드를 결합, 날짜 시간을 반환하는 확장 메서드 만들기 - 다음 그저 그의를 :

다음과 같이 귀하의 람다 전화를 변경

.

말했다 로직은 또한뿐만 아니라 정렬 식에 직접 사용할 수 있지만, 당신은 확장 방법 :

공공 정적 날짜 시간에 GetDate (이 MyListItem myListItem) { 반환 날짜 시간을 사용하지 않습니다 .구문 분석 (myListItem.date) .AddHours (myListItem.Hour); }

2

위의 코드가 포맷의 유무에 관계없이 완벽하게 작동합니다. 이러한 잘못된 행동에 대한 이유가 없습니다.

List<MyListItem> myList = new List<MyListItem>(); 

     getsomedata(myList); //populate list 

     myList.Sort((a, b) => (a.date + a.Hour.ToString("00")).CompareTo(b.date + b.Hour.ToString("00"))); 

    private void getsomedata(List<MyListItem> items) 
    { 
     for (int i = 1; i < 30; i += 3) 
     { 
      items.Add(new MyListItem("2010-12-05", i)); 
     } 
     for (int i = 2; i < 30; i += 3) 
     { 
      items.Add(new MyListItem("2010-12-05", i)); 
     } 
    } 

    class MyListItem 
    { 
     public MyListItem(string date, int hour) { this.date = date; this.Hour = hour; } 
     public string date; //date in the format "2010-12-05" 
     public int Hour; //hour of day as an int 
    } 
관련 문제