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?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

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:
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
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
JavaScript Best Practices

Save hours in development time and avoid common mistakes by learning the best practices to use for JavaScript.

Mike TomlinsonHigh School Computer Science, Computer Applications, and Mathematics TeachersCommented:
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
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
.NET Programming

From novice to tech pro — start learning today.