使用公共密钥加入和分组2列表

时间:2015-03-30 09:52:51

标签: c# linq

我有两个不同类的列表,其中State(在Pet中)和Region(在Person中)可以包含相同的字符串值。我试图得到这样的输出:

州/地区1:

  • State1中的宠物;

  • Region1的人。

即使其中一个列表没有,也应显示每个键值的结果。我所制作的代码有效,但看起来很笨重。我想知道是否还有其他方法可以实现它。

        Person magnus = new Person { FirstName = "Magnus", LastName = "Hedlund", Region="Texas" };
        Person terry = new Person { FirstName = "Terry", LastName = "Adams", Region="NY" };
        Person charlotte = new Person { FirstName = "Charlotte", LastName = "Weiss", Region="Texas" };
        Person arlene = new Person { FirstName = "Arlene", LastName = "Huff",Region="Corolado" };
        Person rui = new Person { FirstName = "Rui", LastName = "Raposo",Region="Texas" };
        Person phyllis = new Person { FirstName = "Phyllis", LastName = "Harris", Region="California" };

        Pet barley = new Pet { Name = "Barley", Owner = terry, State="NY" };
        Pet boots = new Pet { Name = "Boots", Owner = terry, State="New Jersey" };
        Pet whiskers = new Pet { Name = "Whiskers", Owner = charlotte, State="Texas" };
        Pet daisy = new Pet { Name = "Daisy", Owner = magnus, State="NY" };

        List<Person> people = new List<Person> { magnus, terry, charlotte,arlene, rui,phyllis };
        List<Pet> pets = new List<Pet> { barley, boots, whiskers, daisy };

        //join pets with associated people on Region\State
        var resultQuery =( from pet in pets
                       group pet by pet.State into petGroup
                       join person in people on petGroup.Key equals person.Region into persGroup
                           select new Container { Key = petGroup.Key, Pets = petGroup, People = persGroup }
                       ).ToList();

        var persQuery = from person in people
                        group person by person.Region;
        //add people groups that have no equivalent in pet groups to the result
        foreach (IGrouping<string, Person> gr in persQuery)
        {
            if (resultQuery.All(_container => !_container.Key.Contains(gr.Key)))
                resultQuery.Add(new Container { Key = gr.Key, Pets = new List<Pet>(), People = gr });//have to use Container here
        }

        //show results
        foreach (var _container in resultQuery)
        {
            Console.WriteLine("Key(Region): {0}", _container.Key);
            foreach (Pet pet in _container.Pets) Console.WriteLine(pet.Name);
            foreach (Person per in _container.People)
                Console.WriteLine(per.FirstName);
        }

我还必须添加类Container而不是使用匿名类型来执行.Add方法

1 个答案:

答案 0 :(得分:0)

我使用过union和group by,可能是更好的方法。除了这个解决方案之外,现在我什么都没想到。试试这个!!!

Person magnus = new Person { FirstName = "Magnus", LastName = "Hedlund", Region = "Texas" };
        Person terry = new Person { FirstName = "Terry", LastName = "Adams", Region = "NY" };
        Person charlotte = new Person { FirstName = "Charlotte", LastName = "Weiss", Region = "Texas" };
        Person arlene = new Person { FirstName = "Arlene", LastName = "Huff", Region = "Corolado" };
        Person rui = new Person { FirstName = "Rui", LastName = "Raposo", Region = "Texas" };
        Person phyllis = new Person { FirstName = "Phyllis", LastName = "Harris", Region = "California" };

        Pet barley = new Pet { Name = "Barley", Owner = terry, State = "NY" };
        Pet boots = new Pet { Name = "Boots", Owner = terry, State = "New Jersey" };
        Pet whiskers = new Pet { Name = "Whiskers", Owner = charlotte, State = "Texas" };
        Pet daisy = new Pet { Name = "Daisy", Owner = magnus, State = "NY" };

        List<Person> people = new List<Person> { magnus, terry, charlotte, arlene, rui, phyllis };
        List<Pet> pets = new List<Pet> { barley, boots, whiskers, daisy };


        var petsGroupQuery = (from pet in pets
                              group pet by pet.State into petGroup
                              select new Container { Key = petGroup.Key, Pets = petGroup.Select(x => x).ToList(), People = new  List<Person> ()}).Union
                              (from pep in people
                               group pep by pep.Region into pepGroup
                               select new Container { Key = pepGroup.Key, Pets = new List<Pet>(), People = pepGroup.Select(x => x).ToList() }).GroupBy
                               (x => x.Key)
                               .Select(t => new Container {Key = t.Key, People = t.SelectMany(x => x.People), Pets = t.SelectMany(x => x.Pets) });
        //// printing
        petsGroupQuery.ToList().ForEach(x =>
            {
                Trace.WriteLine(x.Key);
                Trace.WriteLine(string.Join(",", x.People.Select(t => t.FirstName)));
                Trace.WriteLine(string.Join(",", x.Pets.Select(t => t.Name)));
            });