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.

Comments
Finally, someone showing LINQ, extension methods, and delegates. It's rare around here.

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

This question has already been answered. Start a new discussion instead.