C# Program List Iteration

Experts,

I`m using VS 2008 C# 3.5 Maybe this question belongs in the Algorithm section.

Please look at the code below, and I think this is overkill - the number of iterations is way too much and costing performance. A more efficient algorithm would be greatly appreciated.
namespace WindowsFormsApplication9
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //This is a very simple example of what I`m trying to do. For the sake of simplicity I`ve take a Car info example.

            //This is just list of Class DumClass. Which contains ID, EnumValue (Name, Year and Model) and StrValue
            List<DumClass> DumList = new List<DumClass>();

            DumList.Add(new DumClass(00, EnumType.Model, "Audi"));
            DumList.Add(new DumClass(00, EnumType.Name, "A6"));
            DumList.Add(new DumClass(01, EnumType.Model, "Toyota"));
            DumList.Add(new DumClass(01, EnumType.Year, "1998"));
            DumList.Add(new DumClass(10, EnumType.Name, "Honda"));
            DumList.Add(new DumClass(10, EnumType.Year, "2004"));
            DumList.Add(new DumClass(10, EnumType.Name, "Civic"));

            //I want to display the information in this format.
            //Notice for every ID, some information might be absent.

            //Function here - Display
            //ID   Name   Year   Model
            //00   A6            Audi
            //01          1998   Toyota
            //10   Honda  2004   Civic


            //I create a list of IDs.
            List<int> IDList = new List<int>();

            for (int i = 0; i < DumList.Count; i++)
            {
                IDList.Add(DumList[i].ID);
            }

            //Sort the IDs and make it unique.
            IDList.Sort();
            IDList = IDList.Distinct().ToList();

            //Loop through the IDs through the Dumlist and see if the information is present. 
            //If present write it. 

            //Lets say, I have a IDList has a few 1000 unique entries and then the DumList has another 50000 entries.
            //Thats 1000 * 50000 iterations!! 
            //There should be a better way of doing this.
            for (int i = 0; i < IDList.Count; i++)
            {
                int ID = IDList[i];

                Console.Write(ID + "\t");
            
                for (int j = 0; j < DumList.Count; j++)
                {
                    DumClass DObj = DumList[j];

                    if (ID == DObj.ID)
                    {
                        if (DObj.EnumVal == EnumType.Name)
                        {
                            Console.Write(DObj.StrValue + "\t");
                        }
                        else
                        {
                            Console.Write("\t");
                        }

                        if (DObj.EnumVal == EnumType.Year)
                        {
                            Console.Write(DObj.StrValue + "\t");
                        }
                        else
                        {
                            Console.Write("\t");
                        }

                        if (DObj.EnumVal == EnumType.Model)
                        {
                            Console.Write(DObj.StrValue + "\t");
                        }
                        else
                        {
                            Console.Write("\t");
                        }
                    }
                }

                Console.WriteLine();
            }

        }
    }

    public enum EnumType {Name, Year, Model};

    public class DumClass
    {
        public int ID;
        public EnumType EnumVal;
        public string StrValue;
        
        public DumClass(int id, EnumType enumVal, string strVal)
        {
            ID = id;
            EnumVal = enumVal;
            StrValue = strVal;
        }
    }
}

Open in new window

San24Asked:
Who is Participating?
 
wdosanjosConnect With a Mentor Commented:
Please try the following.  It uses a LINQ query.  BTW, ID=10 has two 'Name' entries on your sample, so I updated it to contain a 'Name', 'Year', and 'Model'.

namespace WindowsFormsApplication9
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //This is a very simple example of what I`m trying to do. For the sake of simplicity I`ve take a Car info example.

            //This is just list of Class DumClass. Which contains ID, EnumValue (Name, Year and Model) and StrValue
            List<DumClass> DumList = new List<DumClass>();

            DumList.Add(new DumClass(00, EnumType.Model, "Audi"));
            DumList.Add(new DumClass(00, EnumType.Name, "A6"));
            DumList.Add(new DumClass(01, EnumType.Model, "Toyota"));
            DumList.Add(new DumClass(01, EnumType.Year, "1998"));
            DumList.Add(new DumClass(10, EnumType.Name, "Honda"));
            DumList.Add(new DumClass(10, EnumType.Year, "2004"));
            DumList.Add(new DumClass(10, EnumType.Model, "Civic"));

            //I want to display the information in this format.
            //Notice for every ID, some information might be absent.

            //Function here - Display
            //ID   Name   Year   Model
            //00   A6            Audi
            //01          1998   Toyota
            //10   Honda  2004   Civic


            var query = from car in DumList
                        orderby car.ID
                        group car by car.ID into g
                        select new { 
                            ID = g.Key, 
                            Name = g.Max(c => (c.EnumVal == EnumType.Name) ? c.StrValue : ""), 
                            Model = g.Max(c => (c.EnumVal == EnumType.Model) ? c.StrValue : ""),
                            Year = g.Max(c => (c.EnumVal == EnumType.Year) ? c.StrValue : "")
                        };
			
            foreach (var car in query)
            {
                Console.WriteLine("{0}\t{1}\t{2}\t{3}", car.ID, car.Name, car.Year, car.Model);
            }
        }
    }

    public enum EnumType {Name, Year, Model};

    public class DumClass
    {
        public int ID;
        public EnumType EnumVal;
        public string StrValue;
        
        public DumClass(int id, EnumType enumVal, string strVal)
        {
            ID = id;
            EnumVal = enumVal;
            StrValue = strVal;
        }
    }
}

Open in new window

0
 
San24Author Commented:
Separated by commas makes more sense. That way I can open it as a CSV file.

            //ID , Name,   Year,   Model
            //00,   A6,  ,  Audi
            //01, , 1998,  Toyota
            //10 ,  Honda,  2004,   Civic


0
 
wdosanjosCommented:
For comma delimited, just update the foreach as follows:

Console.WriteLine("ID,Name,Year,Model");  // Header

foreach (var car in query)
{
    Console.WriteLine("{0},{1},{2},{3}", car.ID, car.Name, car.Year, car.Model);  // Row
}

Open in new window

0
Cloud Class® Course: Microsoft Exchange Server

The MCTS: Microsoft Exchange Server 2010 certification validates your skills in supporting the maintenance and administration of the Exchange servers in an enterprise environment. Learn everything you need to know with this course.

 
Mike TomlinsonConnect With a Mentor Middle School Assistant TeacherCommented:
Awesome code by wdosanjos!

I'm still learning LINQ so I threw this not as elegant solution together while he had already answered the question.

This approach assumes that the enum values are the default 0, 1, 2, etc and that they are the order you the output  in:
private void button1_Click(object sender, EventArgs e)
        {
            List<DumClass> DumList = new List<DumClass>();

            DumList.Add(new DumClass(00, EnumType.Model, "A6"));
            DumList.Add(new DumClass(00, EnumType.Name, "Audi"));
            DumList.Add(new DumClass(01, EnumType.Name, "Toyota"));
            DumList.Add(new DumClass(01, EnumType.Year, "1998"));
            DumList.Add(new DumClass(10, EnumType.Model, "Civic"));
            DumList.Add(new DumClass(10, EnumType.Year, "2004"));
            DumList.Add(new DumClass(10, EnumType.Name, "Honda"));

            var IDs = (from x in DumList orderby x.ID select x.ID).Distinct();
            foreach (int ID in IDs)
            {
                string[] values = new string[4];
                values[0] = ID.ToString();
                var instances = from y in DumList where y.ID == ID orderby y.EnumVal select y;
                foreach (DumClass instance in instances)
                {
                    values[(int)instance.EnumVal + 1] = instance.StrValue;
                }
                Console.WriteLine(String.Join(",", values));
            }
        }

Open in new window

0
 
San24Author Commented:
wdosanjos - Thats just an amazing peice of code! Very cool.
Idle_Mind    -  You "not as elegant" code is way better than what I started off. Thanks.

Let me implement this method in my code, which is more complex. Also, I`ll update you guys on execution time taken difference. I`m guessing it`ll be phenomenol.  Once I have everything running I`ll assign the points. Thanks a lot guys!
0
 
San24Author Commented:
Year = g.Max(c => (c.EnumVal == EnumType.Year) ? c.StrValue : "")

If I want Year to be a double, and I want a "null" value instead of "" How woul;d I go about that?

Year = g.Max(c => (c.EnumVal == EnumType.Year) ? c.Value : null)   //This throws an error.
                             
0
 
wdosanjosCommented:
In that case you would need something like this:

Year = g.Max(c => (c.EnumVal == EnumType.Year) ? double.Parse(c.StrValue) : (double?)null)
0
 
San24Author Commented:
wdosanjos - Thanks Again. I just implemented everything and the execution time for my data set reduced by 58%. Thats crazy.

I will look into using LINQ more.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.