2009-06-23 4 views
1

나는 여기에있는 누군가가 내가 생각하는 것보다 쉽게 ​​해결할 것이라고 확신한다. 이름과 전화 번호가있는 목록이 있습니다. 이름은 필수이며 중복 될 수 있으며 숫자는 하나 일 수 있지만 필수는 아닙니다..NET 내에서 다른 funcationality를 변경하는 방법?

|name|number| 
|A |2  | 
|A |  | 
|B |  | 
|C |  | 
|C |  | 
|D |4  | 
------------- 

현재로서는 이름 부분에 list.Distinct()를 수행하고 있지만 숫자 섹션은 신경 쓰지 않습니다.

newlist = oldlist.Distinct().ToList(); 

복제 된 하나의 이름에 번호가있는 경우 해당 번호와 함께 번호를 유지하고 싶습니다. 두 개의 동일한 이름과 두 개의 다른 숫자의 경우는 발생하지 않습니다. 어떤 아이디어?

한 가지 더 :이 시점에서 나는 별개의 것이므로 신경 쓰지 않는다.

나는 StackOverflow에 팀의 더 나은 가시성을 위해 모든 코드를 추가하고 :

class _ClientComparer : IEqualityComparer<_Client> 
{ 
    #region IEqualityComparer<_Client> Members 

    public bool Equals(_Client x, _Client y) 
    { 
     if ((x.ClientNumber != 0) && (y.ClientNumber != 0))//Both clients with numbers 
      if (x.ClientNumber == y.ClientNumber)//both clients number the same then same clients. 
       return true; 
      else //if not the same they are different 
       return false; 
     else if (x.ClientName == y.ClientName) 
      return true; 
     else 
      return false; 
    } 

    public int GetHashCode(_Client obj) 
    { 
     if (obj.ClientNumber != 0) 
      return obj.ClientNumber.GetHashCode(); 
     else 
      return obj.ClientName.GetHashCode(); 
    } 

을 구별를 호출 IEqualityComparer 구현을 위 아래.

 public List<_Client> CollectAllClients() 
    { 
     List<_Client> ClientList = new List<_Client>(); 
     while (this.Read()) 
     { 
      if (GetClientNumber() != 0) 
       ClientList.Add(CreateClientInstance()); 
      else 
       ClientList.AddRange(CreateClientsInstance()); 
     } 
     ClientList = ClientList.Distinct<_Client>(new _ClientComparer()).ToList<_Client>() ; 
     return ClientList; 
    } 
+0

몇 가지 추가 코드를 제공 할 수 있습니다 (정확히'oldList'는 무엇이며 맞춤 클래스는 어떻게 보이는지 등). – Groo

+0

귀하의 의견에 감사드립니다. 이 질문과 관련된 모든 코드를 추가했습니다. 도움이되는지 알려 주시기 바랍니다. – Geo

답변

0

시도 당신의 유형에 대한 IEqualityComparer를 구현하고, (나는 당신의 목록을 튜플은 .NET 클래스되지 않습니다 (문자열의 튜플과 Null 허용 INT를 잡고 있으리라 믿고있어 고유의 매개 변수로 전달 -까지 닷넷 4.0)

 private class c : IEqualityComparer<Tuple<string,int?>> 
     { 

      #region IEqualityComparer<Tuple<string,int?>> Members 

      public bool Equals(Tuple<string, int?> x, Tuple<string, int?> y) 
      { 
       if (x.a.Equals(x.a) && x.b.Equals(y.b)) 
        return true; 
       return false; 
      } 

      public int GetHashCode(Tuple<string, int?> obj) 
      { 
       throw new NotImplementedException(); 
      } 

      #endregion 
     } 

과 같이 목록이 객체로 구성되어 있다면

List<Tuple<string,int?>> list; 
..... 
list.Distinct(new c()); 
+0

나는 이것이 OP가 원하지 않는 "A"와 "A2"를 모두 유지할 것이라고 생각합니다. – Groo

+0

x.a.Equals (x.a) 확실히 항상 true 또는 nullreferenceexception을 던지기를 바란다 :) –

+0

이것은 실제로 프로덕션 준비가 된 코드가 아닙니다. –

0

:

class Record : IEquatable<Record> 
{ 
    public string Name { get; set; } 
    public int Number { get; set; } 

    public bool Equals(Record r) 
    { 
     if (r == null) return false; 
     return this.Name.Equals(r.Name) && this.Number.Equals(r.Number); 
    } 
} 

여기서 0은 숫자가 없음을 나타냅니다. 먼저 정렬하고 결과를 구별하여 결과를 얻습니다. Distinct는 각 요소의 해시 테이블을 유지하고 후속 요소에 존재 여부를 확인합니다. 그래서 :

var newList = oldList.OrderByDescending(x => x.Number).Distinct(); 
1

당신은 그룹화 를 사용할 수 있습니다

 List<MyObject> tests = new List<MyObject>() 
     { 
      new MyObject {Name = "A", Number = 2 }, 
      new MyObject {Name = "A", Number = null }, 
      new MyObject {Name = "B", Number = null}, 
      new MyObject {Name = "C", Number = null}, 
      new MyObject {Name = "C", Number = null}, 
      new MyObject {Name = "D", Number = 4} 
     }; 

     var qry = from t in tests 
        group t by t.Name into g 
        select g.Max(); 

     qry.ToList(); 

MyObject 존재로 :

public class MyObject : IComparable<MyObject> 
{ 
    public string Name { get; set; } 
    public int? Number { get; set; } 

    public int CompareTo(MyObject other) 
    { 
     return Comparer<int?>.Default.Compare(this.Number, other.Number); 
    } 
} 

당신은 (다른 번호와 반복되는 요소가있는 경우 같은 {A, 1} , {A, 2}), Max이 선택됩니다.

관련 문제