Admiral Land
Admiral Land

Reputation: 2492

How to organize the collection according to a certain rule?

I have class:

 public class ClassA
 {
   public String ClassName {get;set;}
   public int ClassId {get;set;}
   public Guid UID {get;set}
  }

Where 'ClassName' may be: A,B,C,D and 'ClassId':10,20,30,40;

And unordered collection:

List<ClassA> unorderedCollection=GetCollection();

And I want to organize the collection in the following order:

  1. A
  2. B
  3. C
  4. D

or from ClassId:

  1. 10
  2. 20
  3. 30
  4. 40

Values can be completely different and they are not related to each other. For example, a class with index 10 is not associated with a class with index 20.

So, for example:

   List<ClassA> unorderedCollection=GetCollection(); 
    /* has values:
      {
         B,
         20,
         uid             
      },
      {
         B,
         20,
         uid
      },
      {
         A,
         10,
         uid             
      },
      {
         A,
         10,
       uid             
      },
      { 
         C,
         30,
         uid             
      },
      {
         D,
         40,
         uid             
      },

    /*

And ordered collection should be:

   /*
     {
         A,
         10,
         uid             
      },
      {
         A,
         10,
         uid             
      },
      {
         B,
         20,
         uid             
      },
      {
         B,
         20,
         uid             
      },
      {
         C,
         30,
         uid             
      },
      {
         D,
         40,
         uid             
      },
  */

I try to use OrderBy but I did not manage to achieve the desired result.

How i can do that?

Upvotes: 0

Views: 52

Answers (4)

AlanT
AlanT

Reputation: 3663

If we want to order by the ClassName in a non-alphabetic way we can use a Comparer.

Say we want to sort the ClassA objects by class name in the order B,C,A,D we can use the following

private class ClassAComparer : Comparer<ClassA>
{
    private IDictionary<string, int> _lookup = new Dictionary<string, int>
    {
        {"B", 1},
        {"C", 2},
        {"A", 3},
        {"D", 4},
    };

    public override int Compare(ClassA x, ClassA y)
    {
        return _lookup[x.ClassName].CompareTo(_lookup[y.ClassName]);
    }
}

Which we use

//...

var ordered = unordered.OrderBy(n => n, new ClassAComparer());

//…

Upvotes: 1

Admiral Land
Admiral Land

Reputation: 2492

I do it! Here is answer:

    _orderClasses : {A:0, B:1,C:2,D:3}  //0,1,2- is an target order

       var indexes = new Dictionary<string, int>();

        for (int i = 0; i < _orderClasses.Count; i++)
        {                            
            indexes.Add(_orderClasses[i].Name, i);
        }

        var results = _unOrderedResults.OrderBy(x => indexes[x.ClassName]).ToArray();

Upvotes: 0

jdweng
jdweng

Reputation: 34429

Here is code that works.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
       static void Main(string[] args)
        {

           List<ClassA> unorderedCollection= new List<ClassA>() {
               new ClassA() { ClassName = "B",  ClassId = 20, UID = new Guid(new byte[] {0,1,2,3,4,5,6,7,8,9,0xA,0xB,0xC,0xD,0xE,0xF})},
               new ClassA() { ClassName =  "B", ClassId = 20, UID = new Guid(new byte[] {0,1,2,3,4,5,6,7,8,9,0xA,0xB,0xC,0xD,0xE,0xF})},
               new ClassA() { ClassName =  "A", ClassId = 10, UID = new Guid(new byte[] {0,1,2,3,4,5,6,7,8,9,0xA,0xB,0xC,0xD,0xE,0xF})},
               new ClassA() { ClassName =  "A", ClassId = 10, UID = new Guid(new byte[] {0,1,2,3,4,5,6,7,8,9,0xA,0xB,0xC,0xD,0xE,0xF})},
               new ClassA() { ClassName =  "C", ClassId = 30, UID = new Guid(new byte[] {0,1,2,3,4,5,6,7,8,9,0xA,0xB,0xC,0xD,0xE,0xF})},
               new ClassA() { ClassName =  "D", ClassId = 40, UID = new Guid(new byte[] {0,1,2,3,4,5,6,7,8,9,0xA,0xB,0xC,0xD,0xE,0xF})},
           };

           List<ClassA> results = unorderedCollection.OrderBy(x => x.ClassName).ThenBy(x => x.ClassId).ToList();


        }


    }
    public class ClassA
    {
        public String ClassName {get;set;}
        public int ClassId {get;set;}
        public Guid UID { get; set;  }
    }

}

Upvotes: 1

D-Shih
D-Shih

Reputation: 46239

You can try to use OrderBy and ThenBy

ThenBy method after OrderBy to sort the collection on another field in ascending order.

 unorderedCollection.OrderBy(x => x.ClassName).ThenBy(y => y.ClassId);

Upvotes: 2

Related Questions