C#LINQ如何将父列表和两个嵌套的子列表拼合成一个新列表

时间:2012-08-24 16:04:33

标签: c# linq list

我需要将父列表和两个子列表压缩到一个列表中。我怎么能用c#和linq做到这一点?

这是我的代码......

public class Customer
{
    public string FirstName { get; set;}
    public string LastName { get; set;}
    // need to flatten these lists
    public List<CreditCard> CreditCards { get; set;}
    public List<Address> Addresses{ get; set;}
}

//  Customer has CreditCards list and Addresses list
List<Customer> allCustomers = _db.GetAllCustomers();

// how to flatten Customer, CreditCards list, and Addresses list into one flattened record/list?

var result = allCustomers.GroupBy().SelectMany(); // how to flatten nested lists?

因此,结果列表将包含看起来像这样扁平化的项目:

Joe,Blow,Visa,Master Card,38 Oak Street,432 Main Avenue

Sally,Cupcake,Discover,Master Card,29 Maple Grove,887 Nut Street

它会使客户FirstName,LastName,CreditCards列表和地址列表变平。

感谢您的反馈!

5 个答案:

答案 0 :(得分:4)

实施IEnumerable

public class Customer : IEnumerable<string>
{
    public string FirstName {get; set;}
    public string LastName {get; set;}
    public List<CreditCard> CreditCards {get; set;}
    public List<Address> Addresses{get; set;}

    public IEnumerator<string> GetEnumerator()
    {
        yield return FirstName;
        yield return LastName;
        foreach (CreditCard c in CreditCards)
        {
            yield return c.ToString();
        }
        foreach (Address a in Addresses)
        {
            yield return a.ToString();
        }
    }
}

...

var result = allCustomers.SelectMany(c => c);

注意:这只是一个例子。

答案 1 :(得分:1)

如果要将所有内容展平为一个列表,请使用SelectMany。在这种情况下,您仍然希望每个客户都有一条记录,因此您不需要展平。

对于像你的例子这样的数组,这样的东西应该可以工作:

var result = customers
   .Select(customer => new[]
   {
      customer.FirstName,
      customer.LastName
   }
   .Concat(customer.CreditCards.Select(cc => cc.ToString()))
   .Concat(customer.Addresses.Select(address => address.ToString())));

答案 2 :(得分:0)

将每种类型投放到object,然后使用Union展平它们。

        var allCreditCards = from customer in allCustomers
                             from creditCard in customer.CreditCards
                             select (object)creditCard;

        var allAddresses = from customer in allCustomers
                           from address in customer.Addresses
                           select (object)address;

        var flat = allCustomers.Concat(allCreditCards).Concat(allAddresses);

当项目属于不同的类型时,我不确定平展IEnumerable<object>的价值,但这就是你的方式。

答案 3 :(得分:0)

这使用linq到对象,因为它依赖于string.Join:

allCustomers.Select(c=>
  new { FirstName = c.FirstName, LastName= c.LastName,
     CardsList = string.Join(",", c.CreditsCards.Select(c=> c.CardName))
     AddressesList = string.Join(",", c.Addresses.Select(c=> c.Street)
  }
)

答案 4 :(得分:0)

根据您的修改,这将为您提供所需的IEnumerable<string>

var flatenned = from c in allCustomers
                select
                    c.FirstName + ", " +
                    c.LastName + ", " +
                    String.Join(", ", c.CreditCards.Select(c2 => c2.Name).ToArray()) + ", " +
                    String.Join(", ", c.Addresses.Select(a => a.Street).ToArray());

输出:

  

Joe,Blow,Visa,Master Card,38 Oak Street,432 Main Avenue

     

Sally,Cupcake,Discover,Master Card,29 Maple Grove,887 Nut Street

完整的测试代码:

使用System; 使用System.Collections.Generic; 使用System.Linq; 使用System.Text;

命名空间Console40 {     LinqFlatten班     {

    public class Customer
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        // need to flatten these lists
        public List<CreditCard> CreditCards { get; set; }
        public List<Address> Addresses { get; set; }
    }

    public class CreditCard
    {
        public string Name { get; set; }
    }

    public class Address
    {
        public string Street { get; set; }
    }

    public static void Test()
    {
        //  Customer has CreditCards list and Addresses list
        List<Customer> allCustomers = GetAllCustomers();

        // how to flatten Customer, CreditCards list, and Addresses list into one flattened record/list?

        var flatenned = from c in allCustomers
                        select
                            c.FirstName + ", " +
                            c.LastName + ", " +
                            String.Join(", ", c.CreditCards.Select(c2 => c2.Name).ToArray()) + ", " +
                            String.Join(", ", c.Addresses.Select(a => a.Street).ToArray());

        flatenned.ToList().ForEach(Console.WriteLine);
    }

    private static List<Customer> GetAllCustomers()
    {
        return new List<Customer>
                   {
                       new Customer
                           {
                               FirstName = "Joe",
                               LastName = "Blow",
                               CreditCards = new List<CreditCard>
                                                 {
                                                     new CreditCard
                                                         {
                                                             Name = "Visa"
                                                         },
                                                     new CreditCard
                                                         {
                                                             Name = "Master Card"
                                                         }
                                                 },
                               Addresses = new List<Address>
                                               {
                                                   new Address
                                                       {
                                                           Street = "38 Oak Street"
                                                       },
                                                   new Address
                                                       {
                                                           Street = "432 Main Avenue"
                                                       }
                                               }
                           },
                       new Customer
                           {
                               FirstName = "Sally",
                               LastName = "Cupcake",
                               CreditCards = new List<CreditCard>
                                                 {
                                                     new CreditCard
                                                         {
                                                             Name = "Discover"
                                                         },
                                                     new CreditCard
                                                         {
                                                             Name = "Master Card"
                                                         }
                                                 },
                               Addresses = new List<Address>
                                               {
                                                   new Address
                                                       {
                                                           Street = "29 Maple Grove"
                                                       },
                                                   new Address
                                                       {
                                                           Street = "887 Nut Street"
                                                       }
                                               }
                           }
                   };
    }
}

}