1

我需要将一个父列表和两个子列表扁平化为一个列表。如何使用 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

萨莉,纸杯蛋糕,发现,万事达卡,29 Maple Grove,887 Nut Street

它将展平客户的 FirstName、LastName、CreditCards 列表和 Addresses 列表。

感谢您的任何反馈!

4

5 回答 5

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);

注意:这只是一个例子。

于 2012-08-24T16:11:42.093 回答
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())));
于 2012-08-24T16:12:53.753 回答
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)
  }
)
于 2012-08-24T16:13:45.417 回答
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>当项目都是不同类型时扁平化的价值,但这就是你要做的。

于 2012-08-24T16:09:59.760 回答
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

萨莉,纸杯蛋糕,发现,万事达卡,29 Maple Grove,887 Nut Street

完整的测试代码:

使用系统;使用 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"
                                                       }
                                               }
                           }
                   };
    }
}

}

于 2012-08-24T16:30:37.287 回答