C#嵌套类List<>

时间:2017-04-14 06:36:34

标签: c#

我在下面有C#课程,并希望根据该人居住的地址创建不同家庭的列表。如果他们有相同的地址,他们就是家人。所以它应该有一个家庭清单,每个家庭都有一份家庭成员名单。

    public class Person
    {
        public string firstName;
        public string lastName;
        public Address address;

        public Person(string f, string l, string addr, string city, string state)
        {
            firstName = f;
            lastName = l;    
            address= new Address(addr, city, state);
        }
    }

   public class Family
    {
        public string familyAddress;//maybe I don't need this
        public List<Person> personList;

        public Family()
        {
            personList = new List<Person>();
        }

        public void AddPerson(Person p)
        {
            personList.Add(p);
        }

        public string FamilyAddress //maybe I dont need this
        {
            get
            {
                return familyAddress;
            }
            set
            {
                familyAddress= value;
            }
        }
    }

   public partial class Form1 : Form
    {
        public List<Family> familyList;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            familyList= new List<Family>();
            ReadCustomerFile("..\\Customers.txt");
        }

        private void ReadCustomerFile(file)
        {
            var lines = File.ReadAllLines(file);                
            var reg = new Regex("(?:^|,)(\"(?:[^\"]+|\"\")*\"|[^,]*)");

            for (int i = 0; i < lines.Length; i++)
            {
                var data = reg.Matches(lines[i]).Cast<Match>().Select(m => m.Value).ToArray();

                //data[0] contains first name
                //data[1] contains last name
                //data[2] contains street
                //data[3] contains city
                //data[4] contains state

            //In here as I read the customer text file, i would 
            //like to add the person that has the same address into 
            //the same family.
            //for example:
            //familyList address: "800 NE Oregon St.  Portland, OR" has
            //                     "Steve Jones"
            //                     "Sarah Jones"
            //                     "Alisa Jones"

            //familyList address: "2525 Lake Park. Salt Lake City, UT" has
            //                     "Joey William"
            //                     "Becky William"
            //                     "Sam William"
            }
        }
    }

更新#1-基于Tempx评论:谢谢!

   public partial class Form1 : Form
    {
        public List<Family> familyList;
        public List<Person> personList;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            familyList= new List<Family>();
            personList = new List<Person>();                

            ReadCustomerFile("..\\Customers.txt");
        }

        private void ReadCustomerFile(file)
        {
            var lines = File.ReadAllLines(file);                
            var reg = new Regex("(?:^|,)(\"(?:[^\"]+|\"\")*\"|[^,]*)");

            for (int i = 0; i < lines.Length; i++)
            {
                var data = reg.Matches(lines[i]).Cast<Match>().Select(m => m.Value).ToArray();

                //data[0] contains first name
                //data[1] contains last name
                //data[2] contains street
                //data[3] contains city
                //data[4] contains state
                Person person = new Person(data[0].Trim(','),
                                            data[1].Trim(','),
                                            data[2].Trim(','),
                                            data[3].Trim(','),
                                            data[4].Trim(','));
                personList.Add(person);
            }

            //In here as I read the customer text file, i would 
            //like to add the person that has the same address into 
            //the same family.
            //for example:
            //familyList address: "800 NE Oregon St.  Portland, OR" has
            //                     "Steve Jones"
            //                     "Sarah Jones"
            //                     "Alisa Jones"

            //familyList address: "2525 Lake Park. Salt Lake City, UT" has
            //                     "Joey William"
            //                     "Becky William"
            //                     "Sam William"

            var familyAddress = new Dictionary<Address, Family>();
            Family family;
            foreach (Person p in personList)
            {
                // Returns true if the familyAddess contains the address of the person
                if (familyAddress.TryGetValue(p.address, out family))
                    //if such family exists add the person the family  
                    family.AddPerson(p);
                else // no family is found with the person's address
                {
                    //create a new family
                    family = new Family();
                    //add person to the family
                    family.AddPerson(p);
                    //add the family to the familyAddress dictionary
                    familyAddress.Add(p.address, family);
                }
            }

        }
    }

本声明

if (familyAddress.TryGetValue(p.address, out family))

始终返回系列不存在,因此转到else语句

更新#2-现在可以添加到家庭的人。但是现在有时人的地址在地址中有逗号和句号,即使街道名称,城市和州都相同。因此它导致Dictionary键TryGetValue()返回不需要的结果。 TryGetValue()是否可以忽略逗号和句点?感谢

   public partial class Form1 : Form
    {
        public List<Family> familyList;
        public List<Person> personList;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            familyList= new List<Family>();
            personList = new List<Person>();                

            ReadCustomerFile("..\\Customers.txt");
        }

        private void ReadCustomerFile(file)
        {
            var lines = File.ReadAllLines(file);                
            var reg = new Regex("(?:^|,)(\"(?:[^\"]+|\"\")*\"|[^,]*)");

            for (int i = 0; i < lines.Length; i++)
            {
                var data = reg.Matches(lines[i]).Cast<Match>().Select(m => m.Value).ToArray();
                Person person = new Person(data[0].Trim(','),
                                            data[1].Trim(','),
                                            data[2].Trim(','),
                                            data[3].Trim(','),
                                            data[4].Trim(','));
                personList.Add(person);
            }

            var familyAddress = new Dictionary<string, Family>();
            Family family;
            foreach (Person p in personList)
            {
                // Returns true if the familyAddess contains the address of the person
                if (familyAddress.TryGetValue(p.address.GetAddress(), out family))
                    //if such family exists add the person the family  
                    family.AddPerson(p);
                else // no family is found with the person's address
                {
                    //create a new family
                    family = new Family();
                    //add person to the family
                    family.AddPerson(p);
                    //add the family to the familyAddress dictionary
                    familyAddress.Add(p.address, family);
                }
            }

        }
    }

UPDATE#3-我决定将地址字符串格式化为正确的格式,然后再添加为Dictionary in Key。在Tempx建议之后转换为如下所示的列表:

var valueList = familyAddress.Values.ToList();

如何遍历列表?因为我尝试以下:

        foreach (var h in valueList)
        {
            foreach(var p in h)
            {
               //I cannot access the Person data?
            }
        }

由于

2 个答案:

答案 0 :(得分:1)

我相信您希望将此人添加到正确的家庭,并相信您可以使用词典来完成工作。

public List<Person> personList;

//a specific address points to a specific family
var familyAddress = new Dictionary<Address, Family>();

一开始我假设personList不是空的,而是familyAddress。

然后,在您的代码中,人员列表的for语句可以写为

foreach (person p in personList)
{   
    // Returns true if the familyAddess contains the address of the person
    if (familyAddress .TryGetValue(p.Address, out family))
        //if such family exists add the person the family  
        family.AddPerson(p);
    else // no family is found with the person's address
    {
      //create a new family
      family = new Family();
      //add person to the family
      family.AddPerson(p);
      //add the family to the familyAddress dictionary
      familyAddress.add(p.Address, family);
    }
}

您可以检索家庭列表

familyAddress.Values.ToList();

PS:正如其他评论者所说,我也相信Family类familyAddress应该是Address的类型。

答案 1 :(得分:1)

如果您想使用LINQ,可以通过LINQ将StructType(StructField(A1,ArrayType(StringType,true),true), StructField(A2,StringType,true), StructField(A3,IntegerType,true),StructField(A4,ArrayType(StringType,true),true) 转换为List<Person>。这是一个扩展方法,可以做到这一点:

List<Family>

然后你可以在代码中的任何地方调用你的方法......

public static class FamilyExtensions
{
    public static List<Family> GroupToFamilies(this List<Person> personList)
    {
        var retval = from p in personList
                     group p by new p.address into f
                     select new Family() { personList = f.ToList() }; //If familyAddress was of type Address, you could add: familyAddress = f.Key
        return retval.ToList();
    }
}

请注意,如果您想按List<Person> people = new List<Person>(); people.Add(new Person("Papa", "Bear", "123 Forest Rd", "Somewhere", "AK")); people.Add(new Person("Mama", "Bear", "123 Forest Rd", "Somewhere", "AK")); people.Add(new Person("Some", "Bear", "567 Woodland Ln", "Somewhere", "AK")); people.Add(new Person("Other", "Bear", "890 Canopy Cr", "Somewhere", "AK")); var families = people.GroupToFamilies(); 进行分组,则需要覆盖p.address课程中的GetHashCode()Equals(object obj)。如果您不想覆盖这两种方法,则可以使用组合键进行分组:

Address

如果您确实希望按from p in personList group p by new { p.address.addr, p.address.city, p.address.state } into f select new Family() { personList = f.ToList() }; 进行分组,请覆盖Address类上的GetHashCode()Equals(object obj),如此...

Address

Here's more information on the group clause in C#