2012-10-03 7 views
2

를 돌려 I는 다음과 같습니다 클래스 정의가 : 나는이 MyObjectModel의 목록을 가지고개체를 비교하고 목록

public class MyObjectModel 
{ 
    public int ObjectID { get; set; } 

    //for when the user's data is split in 2 fields 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 

    //for when the user's data is all in one field 
    public string FirstLastName { get; set; } 
} 

을하고 난 그 경우 검사를 포함하기 때문에 사용자 정의 정렬 프로세스 이름을 정렬 할 데이터가 LastName (이 경우는 LastName을 사용하여 정렬) 또는 FirstLastName (이 경우에는 하나의 단어가있는 경우 두 번째 단어를 구분하고 하나의 단어가있는 경우 전체 문자열 만 정렬합니다. .)

나는 두 가지가 확실하지 않습니다.

  1. IComparer 또는 IComparable을 사용해야합니까?
  2. 일단 정렬 순서를 결정하면 (내가 할 수 있음) 메서드의 출력이 ObjectID을 나타내는 int 목록이되도록 만드는 방법은 무엇입니까?
+1

사용중인 C#의 버전에 따라 Linq을 사용하여 정렬 할 수 있습니다. –

+0

정밀도를 위해 C# 4를 사용하고 있습니다. – frenchie

답변

3

사용 Linq에가 :

List<MyObjectModel> objects = new List<MyObjectModel>(); 
    List<int> ids = objects.OrderBy(o => FunctionWhichReturnsNameForSort(o)).Select(o => o.ObjectID).ToList(); 

FunctionWhichReturnsNameForSort 다른 클래스에서 구현하거나 확장, 또는 구성원으로 할 수있다.

// should be in a static helper class 
public static string NameForSort(this MyObjectModel obj) 
{ 
    if (!string.IsNullOrEmpty(obj.LastName)) return obj.LastName; 

    return obj.FirstLastName.Split(... // your splitting logic goes here 
} 

var ids = objects.OrderBy(o => o.NameForSort()).Select(o => o.ObjectID).ToList(); 
+0

FunctionWhichReturnsNameForSort 함수는 무엇을 반환해야합니까? 그것은 비교 논리에 따라 -1, 0, 1을 반환해야합니까? – frenchie

+0

정렬에 사용 된 이름을 반환해야합니다. 나는 예제를 추가 할 것이다. –

+0

좋습니다, 감사합니다. 저는 이것을 Holterman의 대답과 결합 할 것입니다! – frenchie

1

이 분류 한 사용 사례에 고유 한 경우에는 LINQ 사용하여 수행 할 수 있습니다 : 당신이 정말이 이상한 이중 솔루션을 필요로 할 때

var sortedIds = models.OrderBy(SecondName).Select(m => m.ObjectId).ToList(); 

private static string SecondName(MyObjectModel model) 
{ 
    if (!string.IsNullOrWhitespace(model.LastName)) return model.LastName; 
    return model.FirstLastName.Split(' ').Last(); 
} 
+0

일부 성 (lastname)은 여러 부분 (공백)을 가지고 있습니다. –

+0

이름 문자열에 여러 부분이있는 경우 두 번째 문자열을 비교합니다. – frenchie

2

당신이 더 자주 이것과 비슷한 문제로 실행됩니다 . 보다 일반적인 해결책으로, 몇 읽기 전용 속성의 이름에 대한 비즈니스 로직을 넣어 고려해

//for when the user's data is split in 2 fields 
public string FirstName { get; set; } 
public string LastName { get; set; } 

//for when the user's data is all in one field 
public string FirstLastName { get; set; } 

public string FullName 
{ 
    get { ... } // pick from LastName, FirstName, FirstLastName 
} 

public string SortName 
{ 
    get { ... } // pick from LastName, FirstLastName 
} 

를이 정렬 순서를 결정하면 (내가 그렇게 할 수), 나는 그것을 어떻게해야합니까 방법의 출력이 OBJECTID

result = MyObjectList 
      .OrderBy(m => m.SortName) // sort on SortName 
      .Select(m => m.ObjectID) // select the Id 
      .ToList(); 
+0

나는이 아이디어가 마음에 든다. 객체의 속성에 대한 비교를하는 대신 필자는 정렬중인 문자열을 반환하는 함수의 출력을 비교한다. 이게 네가 말하는거야? – frenchie

+0

예. 특수 속성을 정렬하고 클래스 내부의 논리를 유지합니다. –

+0

좋습니다, 감사합니다! – frenchie

1

당신은 LINQ를 사용할 수 있지만를 나타내는 INT의 목록이되도록 다른 제안으로, 그 기존 목록을 돌연변이하지, 새로운 목록을 작성 포함 것 . 그것은 바람직하지 않을 수도 있습니다.

List<string> list = new List<string>(){"a","b","c"}; 

list.Sort((a,b)=> a.CompareTo(b)); 

는 그냥 목록을 Sort를 호출하고 두 항목을 소요하고 더 큰 있는지를 나타내는 정수를 반환하는 람다 전달 : 당신도 충분히 쉽게 목록 자체를 정렬합니다. 귀하의 경우에는 ab의 일부 메소드를 호출하여 문자열을 얻은 다음 해당 두 문자열에 CompareTo 또는 string.Compare을 사용하십시오.

관련 문제