Domanda

qualcuno può aiutare, ho problema facendo una sorta, ho pensato che avevo ordinato, ma sembra non funzionare.

Ho una lista che memorizza i seguenti valori

8,6,10,11,7

ho anche un altro elenco (accessori nella mia classe ed ha una propert chiamati corrente accessoryId le classi sono in ordine di id che è currenty 6,7,8,10,11)

Quindi devo ordinare loro di 6,7,8,10,11 l'ordine adottato dalla semplice elenco che è 8,6,10,11,7

Ho il mio IComparable (vedi sotto) e sto chiamando come questo - lo fa entrare, ma qualcosa è sbagliato perché la lista ha ancora tutti i miei corsi, ma è ancora in ordine di 6,7,8,10,11

   // accesories is the IList<Accessories> (hence why i am use ToList)
   // and sortOrder is the simple int list list<int>
   accesories.ToList().Sort(new ItemTpComparer(sortOrder));  

class ItemTpComparer : IComparer<Accessories>
{
    private IList<int> otherList;

    public ItemTpComparer(IList<int> otherList)
    {
        this.otherList = otherList;
    }

    #region IComparer<Accessories> Members

    public int Compare(Accessories x, Accessories y)
    {

        if (otherList.IndexOf(x.AccessoryId) > otherList.IndexOf(y.AccessoryId))
            return 1;

        else if (otherList.IndexOf(x.AccessoryId) < otherList.IndexOf(y.AccessoryId))
            return -1;
        else
            return 0;

        // tried below also didn't work
        //return otherList.IndexOf(x.AccessoryId) - otherList.IndexOf(y.AccessoryId);
È stato utile?

Soluzione

L'operatore di confronto è corretta (anche la versione commentata singola riga). Il problema è ToList() crea un nuovo List contenente una copia di elementi nell'oggetto IEnumerable<T> Quindi, fondamentalmente, si sta creando una nuova lista, l'ordinamento e buttarlo via.

var sortedList = accesories.ToList();
sortedList.Sort(new ItemTpComparer(sortOrder)); 

per il quale io suggerirei di sostituire con:

var sortedList = accessories.OrderBy(sortOrder.IndexOf).ToList();

in questo modo, nessuna implementazione di confronto sarebbe necessario. Si potrebbe anche ordinare in ordine decrescente facilmente:

var sortedList = accessories.OrderByDescending(sortOrder.IndexOf).ToList();

Se l'oggetto è davvero List<Accessories>, si potrebbe anche ordinare al suo posto:

((List<Accessories>)accessories).Sort(new ItemTpComparer(sortOrder));

Altri suggerimenti

Mehrdad vi ha mostrato il motivo per cui l'elenco non è stato risolto. Voglio affrontare le prestazioni del l'operatore di confronto, e anche la questione con gli elementi di smistamento di meno che gli elementi ordinati.

Utilizzando IndexOf in un elenco per individuare l'indice è del tutto inefficiente. Mi ha un ciclo tra gli elementi dell'elenco per trovare quella giusta. Utilizzare un dizionario come ricerca, invece, in questo modo si ciclo solo attraverso gli articoli una volta:

class ItemTpComparer : IComparer<Accessories> {

   private Dictionary<int, int> index;

   public ItemTpComparer(IList<int> otherList) {
      index = new Dictionary<int, int>();
      for (int i = 0; i < otherList.Count; i++) {
         index.Add(otherList[i], i);
      }
   }

   public int Compare(Accessories x, Accessories y) {
      return index[x.AccessoryId].CompareTo(index[y.AccessoryId]);
   }

}

Se si desidera consentire l'elenco di valore per l'ordinamento di essere più corta della lista degli elementi da ordinare, si controlla se il valore esiste nel dizionario:

   public int Compare(Accessories x, Accessories y) {
      int xIndex, yIndex;
      if (!index.TryGetValue(x.AccessoryId, out xIndex)) xIndex = int.MaxValue;
      if (!index.TryGetValue(y.AccessoryId, out yIndex)) yIndex = int.MaxValue;
      return xIndex.CompareTo(yIndex);
   }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top