简体   繁体   中英

sorting data from MySQL alphabetically using list<string> & Methods to return sorted list in C#

I'm extracting data from a MySQL database file and load three data items from there into a method called index that extracts Name, surname & Tel Number fields.....main goal is to load all the data in alphabetical order by surname Letter and if two Surnames are matching it should sort them by alphabetical name order.

using Data_Layer;
using System.Collections.Generic;
using System.Data;
using System.Linq;

namespace Business_Logic_Layer
{
    public class BusinessLogic
    {
        public List<PhoneIndex> phoneIndex = new List<PhoneIndex>();

        public void createPhoneIndex()
        {
            string tableName = "customers";

            DataConnection dc = new DataConnection();
            DataSet customers = dc.selectData(tableName);

            foreach (DataRow customer_row in customers.Tables[0].Rows)
            {
                string surname, name, telephone;
                surname = name = telephone = "";

                for (int i = 0; i < customers.Tables[0].Columns.Count; i++)
                {
                    if (customers.Tables[0].Columns[i].ColumnName.StartsWith("contactFirstName"))
                    {
                        name = customer_row.ItemArray[i].ToString();
                    }
                    else if (customers.Tables[0].Columns[i].ColumnName.StartsWith("contactLastName"))
                    {
                        surname = customer_row.ItemArray[i].ToString();
                    }
                    else if (customers.Tables[0].Columns[i].ColumnName.StartsWith("phone"))
                    {
                        telephone = customer_row.ItemArray[i].ToString();
                    }
                }

                // Add the information to the main phoneIndex

                bool added = false;

                PhoneIndexEntry temp_index_entry = new PhoneIndexEntry() { name = name, surname = surname, telephone = telephone };

                for (int i = 0; i < phoneIndex.Count; i++)
                {
                    if (surname.StartsWith(phoneIndex[i].letter))
                    {
                        phoneIndex[i].entries.Add(temp_index_entry);
                        added = true;
                    }
                }

                if (!added)
                {
                    PhoneIndex temp_index = new PhoneIndex() { letter = surname.Substring(0, 1), entries = new List<PhoneIndexEntry>() { temp_index_entry } };
                    phoneIndex.Add(temp_index);
                    added = true;
                }

            }
        } // End of method createPhoneIndex()




        public void sortPhoneIndex()
        {


            // Your code goes here...
            string surname, name;
            surname = name = "";
            List<PhoneIndex> phoneIndex = new List<PhoneIndex>() { };

            PhoneIndexEntry temp_index_entry = new PhoneIndexEntry() { name = name, surname = surname };

            foreach (PhoneIndex index in phoneIndex)//letter, entries sort through letters
            { 

                            string[] sortedLetter = new string[1];

                            for (int i = 0; i < phoneIndex.Count - 1; i++)
                            {
                                for (int j = i + 1; j < phoneIndex.Count; j++)
                                {
                                    if (phoneIndex[i].letter.CompareTo(phoneIndex[j].letter) > 0)
                                    {
                                        sortedLetter[0] = phoneIndex[i].letter;
                                        phoneIndex[i].letter = phoneIndex[j].letter;
                                        phoneIndex[j].letter = sortedLetter[0];
                                    }
                                }
                            }
                //if name==name compare surname for sorting
                return;
                        }

                    }//end of foreach

                } // End of method sortPhoneIndex()

        } // End of Class BusinessLogic



        public class PhoneIndex
        {
            public string letter { get; set; }
            public List<PhoneIndexEntry> entries { get; set; }


        } // End of Class PhoneIndex

        public class PhoneIndexEntry
        {
            public string name { get; set; }
            public string surname { get; set; }
            public string telephone { get; set; }

        } // End of Class PhoneIndexEntry


// End of Namespace Business_Logic_Layer

A =

anthony, adams, 0670510248

B = bill, adams, 0724677987 bill, crucible, 0687944987

Assuming that you cannot change the way in which you retrieve your data from the database then this is a job where Linq could help a lot to simplify your code.

// Example data .....
DataTable dt = new DataTable();
dt.Columns.Add("name", typeof(string));
dt.Columns.Add("surname", typeof(string));
dt.Columns.Add("phone", typeof(string));
dt.Rows.Add("charles", "dickens", "11232");
dt.Rows.Add("mark", "twain", "453446");
dt.Rows.Add("howard", "lovecraft", "875564");
dt.Rows.Add("ernst", "hemingway", "1647567");
dt.Rows.Add("thomas", "mann", "56434");
dt.Rows.Add("isaac", "asimov", "9700");
dt.Rows.Add("aldous", "huxley", "2654");


List<PhoneIndex> phoneIndex = new List<PhoneIndex>();

// Let's enumerate the datatable grouping by first letter in the surname column
var names = dt.AsEnumerable().GroupBy(d => d.Field<string>("surname").Substring(0, 1))
         // foreach group build a sublist with the info from the datarow 
         // transformed in a PhoneIndexEntry.
         .Select(g => g.Select(p => new PhoneIndexEntry 
         {
             name = p.Field<string>("name"),
             surname = p.Field<string>("surname"),
             telephone = p.Field<string>("phone")

         }));

// Now we have an IEnumerable<IEnumerable> where the first enumerable is a list 
// of all distinct first letter from the surname column, while the second
// is an enumerable of PhoneIndexEntry. 
// We can loop over the first Enumerable ordering it
// by the first surname's letter and creating a PhoneIndex with all the PhoneIndexEntry for that specific letter
foreach (var entry in names.OrderBy(n => n.First().surname[0].ToString()))
    phoneIndex.Add(new PhoneIndex { letter = entry.First().surname[0].ToString(), entries = entry.OrderBy(s => s.surname).ToList()});

Side note: It seems that you have a very bad do_it_all method (SelectData) where you pass a table name and you get back all the data from that table.
Surely this is not a good way to query a database and, unless you retrieve very few records, I suggest you to write specific methods for every data extraction or dedicate a bit of time to learn how to use an ORM library.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM