Hi all,

I have a list of Classes and I want to sort the list of Class by one of the Attributes held within the Classes does anyone know a easy way of doing this.

Kind Regards

FlippA

Well, how you do it depends on a few things that you didn't specify, so I'll just throw out one possible solution to get your creative juices flowing:

using System;
using System.Linq;
using System.Globalization;
using System.ComponentModel;
using System.Collections.Generic;

namespace JSW
{
    static class Program
    {
        static void Main()
        {
            List<Type> classes = new List<Type>(
                new Type[] { typeof(Foo), typeof(Bar), typeof(Baz) });

            classes.ForEach(c => Console.WriteLine(c));
            Console.WriteLine();

            var sorted = classes.OrderBy(c => GetDescription(c)).ToList();

            sorted.ForEach(c => Console.WriteLine(c));
        }

        static string GetDescription(Type type)
        {
            Attribute[] attributes = Attribute.GetCustomAttributes(type);
            var descr = (DescriptionAttribute)attributes.SingleOrDefault(
                attr => attr is DescriptionAttribute);

            return descr != null ? descr.Description : "(no description)";
        }
    }

    [Description("B")]
    class Foo { }

    [Description("A")]
    class Bar { }

    [Description("D")]
    class Baz { }
}

Dear Narue,

Hi there thank you for the quick reply, I have to warn you I am not the best programmer in the world just before I start. I understand small bits of your code but is there any chance you could use examples in your code as it gets quite confusing.


It might help if I explain my problem a bit more have a Class called Population and within this Class I have a list called ParentList which contains a list of Class called Chromosomes within each Chromosome there is a variable Punishment. I want to order the ParentList so the Chromosome Class with the smallest value is at the top and the one with the highest is at the bottom.

I hope that makes sense.

Kind Regards

FlippA

Well, how you do it depends on a few things that you didn't specify, so I'll just throw out one possible solution to get your creative juices flowing:

using System;
using System.Linq;
using System.Globalization;
using System.ComponentModel;
using System.Collections.Generic;

namespace JSW
{
    static class Program
    {
        static void Main()
        {
            List<Type> classes = new List<Type>(
                new Type[] { typeof(Foo), typeof(Bar), typeof(Baz) });

            classes.ForEach(c => Console.WriteLine(c));
            Console.WriteLine();

            var sorted = classes.OrderBy(c => GetDescription(c)).ToList();

            sorted.ForEach(c => Console.WriteLine(c));
        }

        static string GetDescription(Type type)
        {
            Attribute[] attributes = Attribute.GetCustomAttributes(type);
            var descr = (DescriptionAttribute)attributes.SingleOrDefault(
                attr => attr is DescriptionAttribute);

            return descr != null ? descr.Description : "(no description)";
        }
    }

    [Description("B")]
    class Foo { }

    [Description("A")]
    class Bar { }

    [Description("D")]
    class Baz { }
}

>I want to order the ParentList so the Chromosome Class with the
>smallest value is at the top and the one with the highest is at the bottom.

Okay, that's completely different. Note that C# already has something called attributes that aren't the same thing as class fields or properties. And you have a list of objects, not a list of classes. Accurate terminology goes a long way toward not confusing people. :)

Anyway, you want something more like this:

using System;
using System.Collections.Generic;

namespace JSW
{
    static class Program
    {
        static void Main()
        {
            var chromosomes = new List<Chromosome>();
            Random rand = new Random();

            for (int i = 0; i < 10; i++)
            {
                chromosomes.Add(new Chromosome(rand.Next(100)));
            }

            chromosomes.ForEach(x => Console.WriteLine(x.Punishment));
            Console.WriteLine();

            // This call to sort is the part you're interested in
            chromosomes.Sort(
                delegate(Chromosome x, Chromosome y)
                {
                    return x.Punishment - y.Punishment;
                });

            chromosomes.ForEach(x => Console.WriteLine(x.Punishment));
        }
    }

    class Chromosome
    {
        public int Punishment { get; set; }

        public Chromosome(int punishment)
        {
            Punishment = punishment;
        }
    };
}

If you're a beginner then you probably want to read up on delegates and anonymous methods/lambdas to fully understand everything in the example.

commented: Finally, someone showing LINQ, extension methods, and delegates. It's rare around here. +1

Hi again,

I am sorry about my terminology I just seem to get confused with all the different terms. I can see how the sample code you provided work and I have gone through it step by step, and I looks like it will work for my problem. I just can't seem to get it working with my code as I have P which equals a population, within P is my ParentList which contains my Chromosomes.

I tried access the Chromosome like
P.ParentList.Sort(delegate P.ParentList x, P.ParentList y),

but this doesn't seem to work, hope this makes sense. Sorry for being confusing just not 100% sure of all the technical terms.

Thanks Again

Chris Weeks


>I want to order the ParentList so the Chromosome Class with the
>smallest value is at the top and the one with the highest is at the bottom.

Okay, that's completely different. Note that C# already has something called attributes that aren't the same thing as class fields or properties. And you have a list of objects, not a list of classes. Accurate terminology goes a long way toward not confusing people. :)

Anyway, you want something more like this:

using System;
using System.Collections.Generic;

namespace JSW
{
    static class Program
    {
        static void Main()
        {
            var chromosomes = new List<Chromosome>();
            Random rand = new Random();

            for (int i = 0; i < 10; i++)
            {
                chromosomes.Add(new Chromosome(rand.Next(100)));
            }

            chromosomes.ForEach(x => Console.WriteLine(x.Punishment));
            Console.WriteLine();

            // This call to sort is the part you're interested in
            chromosomes.Sort(
                delegate(Chromosome x, Chromosome y)
                {
                    return x.Punishment - y.Punishment;
                });

            chromosomes.ForEach(x => Console.WriteLine(x.Punishment));
        }
    }

    class Chromosome
    {
        public int Punishment { get; set; }

        public Chromosome(int punishment)
        {
            Punishment = punishment;
        }
    };
}

If you're a beginner then you probably want to read up on delegates and anonymous methods/lambdas to fully understand everything in the example.

Hi there I have just managed to get it to work using the delegate and anonymous methods function. Thank you very much for your help.

Kind Regards FlippA