Özel Sınıf Listesini Sıralama <T>


112

Listemi datemülk ile sıralamak istiyorum .

Bu benim özel sınıfım:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Test.Web
{
    public class cTag
    {
        public int id { get; set; }
        public int regnumber { get; set; }
        public string date { get; set; }
    }
}

Bir Listsıralamak istediğim şey bu:

List<cTag> Week = new List<cTag>();

Yapmak istediğim date, Listeyi cTag sınıfının özelliğine göre sıralamak . Tarih şu formattadır: gg.MM.yyyy.

IComparableArayüz hakkında bir şeyler okudum , ancak nasıl kullanılacağını bilmiyorum.

Yanıtlar:


143

Bunu yapmanın bir yolu, delegate

List<cTag> week = new List<cTag>();
// add some stuff to the list
// now sort
week.Sort(delegate(cTag c1, cTag c2) { return c1.date.CompareTo(c2.date); });

98
Aynı şeyi bir lambda ifadesiyle de yazabilirsiniz:list.Sort((a,b) => a.date.CompareTo(b.date));
Xavier Poinas

2
@Xavier bazı nedenlerden dolayı aklım her zaman ilk tahminlere atlıyor, ancak Lambda ifadenizin işi bitireceği ve muhtemelen okunması / anlaşılması daha kolay olacağı konusunda% 100 haklısınız.
ahsteele

bu nasıl olur veya lambda ifadesini kullanarak bir bağı tutarlı bir şekilde nasıl bozarsınız? Ya a.date == b.date burada olursa? list.Sort ((a, b) => a.date.CompareTo (b.date)); Bu, sayfalama ızgaralarında sorun yaratır mı ve bu ikisi farklı sayfalara düşer mi?
TheEmirOfGroofunkistan

1
@TheEmirOfGroofunkistan her şey nasıl CompareTouygulandığına bağlıdır . IComparablebir sınıfın yönteme sahip olacağını, ancak bu karşılaştırmanın nasıl yapılacağını sınıf oluşturucuya bağlı olduğunu garanti eder. Date'in ICompare'i nasıl uyguladığından emin değilim, ancak çoğu zaman geliştiricilerin değerler eşit olduğunda bir bağı kırmak için geçirilen sıra parametrelerini kullandıklarını gördüm. hth
ahsteele

51

CTag sınıfınızın IComparable<T>arabirimi uygulaması gerektiği konusunda haklısınız . O zaman Sort()listenizden arayabilirsiniz .

Uygulamak için IComparable<T>bir arayüz, sen uygulamalıdır CompareTo(T other)yöntemi. Bunu yapmanın en kolay yolu, karşılaştırmak istediğiniz alanın, sizin durumunuzda tarih olan CompareTo yöntemini çağırmaktır.

public class cTag:IComparable<cTag> {
    public int id { get; set; }
    public int regnumber { get; set; }
    public string date { get; set; }
    public int CompareTo(cTag other) {
        return date.CompareTo(other.date);
    }
}

Bununla birlikte, bu iyi sıralanmaz, çünkü bu dizelerde klasik sıralama kullanır (tarihi dize olarak bildirdiğiniz için). Bu yüzden yapılacak en iyi şeyin, sınıfı yeniden tanımlamak ve tarihi dize olarak değil, DateTime olarak bildirmek olacağını düşünüyorum. Kod neredeyse aynı kalacaktı:

public class cTag:IComparable<cTag> {
    public int id { get; set; }
    public int regnumber { get; set; }
    public DateTime date { get; set; }
    public int CompareTo(cTag other) {
        return date.CompareTo(other.date);
    }
}

Tarihi içeren dizenizi DateTime türüne dönüştürmek için sınıfın örneğini oluştururken yapmanız gereken tek şey, ancak örneğin DateTime.Parse(String)yöntemle kolayca yapılabilir .


38

Bu durumda, LINQ kullanarak da sıralayabilirsiniz:

week = week.OrderBy(w => DateTime.Parse(w.date)).ToList();

12
List<cTag> week = new List<cTag>();
week.Sort((x, y) => 
    DateTime.ParseExact(x.date, "dd.MM.yyyy", CultureInfo.InvariantCulture).CompareTo(
    DateTime.ParseExact(y.date, "dd.MM.yyyy", CultureInfo.InvariantCulture))
);

9

İlk olarak, date özelliği bir tarihi depoluyorsa, bunu bir DateTime kullanarak depolayın. Tarihi, karşılaştırılan her öğe için ayrıştırmanız gereken sıralamaya göre ayrıştırırsanız, bu çok verimli değildir ...

Daha sonra bir IComparer yapabilirsiniz:

public class TagComparer : IComparer<cTag>
{
    public int Compare(cTag first, cTag second)
    {
        if (first != null && second != null)
        {
            // We can compare both properties.
            return first.date.CompareTo(second.date);
        }

        if (first == null && second == null)
        {
            // We can't compare any properties, so they are essentially equal.
            return 0;
        }

        if (first != null)
        {
            // Only the first instance is not null, so prefer that.
            return -1;
        }

        // Only the second instance is not null, so prefer that.
        return 1;
    }
}

var list = new List<cTag>();
// populate list.

list.Sort(new TagComparer());

Temsilci olarak bile yapabilirsiniz:

list.Sort((first, second) =>
          {
              if (first != null && second != null)
                  return first.date.CompareTo(second.date);

              if (first == null && second == null)
                  return 0;

              if (first != null)
                  return -1;

              return 1;
          });

6

Haklısınız - IComparable'ı uygulamanız gerekiyor. Bunu yapmak için sınıfınızı beyan etmeniz yeterlidir:

public MyClass : IComparable
{
  int IComparable.CompareTo(object obj)
  {
  }
}

CompareTo'da, yalnızca özel karşılaştırma algoritmanızı uygularsınız (bunu yapmak için DateTime nesnelerini kullanabilirsiniz, ancak önce "obj" türünü kontrol ettiğinizden emin olun). Daha fazla bilgi için buraya ve buraya bakın .


7
IComparable<T>o tercih için için kontrol edilir muhtemelen, daha iyi bir seçim olacaktır IComparable: msdn.microsoft.com/en-us/library/b0zbh7b6.aspx
Richard SZALAY

5

Linq'i kullanabilirsiniz:

var q = from tag in Week orderby Convert.ToDateTime(tag.date) select tag;
List<cTag> Sorted = q.ToList()

3

List sınıfının aşırı yüklenmiş Sıralama yöntemine bakın. bunun için bazı yollar var. bunlardan biri: özel sınıfınız IComparable arabirimini uygulamak zorundadır, ardından Cam List sınıfının Sort yöntemini kullanırsınız.


3

Tüm hızlı Cevaplar için teşekkürler.

Bu benim çözümüm:

Week.Sort(delegate(cTag c1, cTag c2) { return DateTime.Parse(c1.date).CompareTo(DateTime.Parse(c2.date)); });

Teşekkürler


2
YourVariable.Sort((a, b) => a.amount.CompareTo(b.amount));
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.