C# C LINQ如何将父列表和两个嵌套的子列表展平到一个新列表中

C# C LINQ如何将父列表和两个嵌套的子列表展平到一个新列表中,c#,linq,list,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;} pub

我需要将父列表和两个子列表展平为一个列表。如何使用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?
因此,结果列表将包含看起来扁平的项,如下所示:

乔,布鲁,维萨,万事达卡,主大街432号橡树街38号

莎莉,纸杯蛋糕,发现,万事达卡,枫树林29号,坚果街887号

它将扁平化客户的名字、姓氏、信用卡列表和地址列表

谢谢你的反馈

将每种类型强制转换为对象,然后使用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的价值,但这就是您应该如何做到的。

将每个类型强制转换为对象,然后使用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展平的值是多少,但您应该这样做。

实现IEnumerable:

注意:这只是一个示例。

实现IEnumerable:


注意:这只是一个示例。

如果要将所有内容平铺到一个列表中,请使用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())));

如果要将所有内容扁平化为一个列表,请使用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())));

这将使用linq转换对象,因为它依赖于字符串。连接:

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

这将使用linq转换对象,因为它依赖于字符串。连接:

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

根据您的编辑,这将为您提供所需的IEnumerable:

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());
产出:

乔,布鲁,维萨,万事达卡,主大街432号橡树街38号

莎莉,纸杯蛋糕,发现,万事达卡,枫树林29号,坚果街887号

完整测试代码:

使用制度; 使用System.Collections.Generic; 使用System.Linq; 使用系统文本

命名空间控制台40 { LinqFlatten类 {


}

根据您的编辑,这将为您提供所需的IEnumerable:

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());
产出:

乔,布鲁,维萨,万事达卡,主大街432号橡树街38号

莎莉,纸杯蛋糕,发现,万事达卡,枫树林29号,坚果街887号

完整测试代码:

使用制度; 使用System.Collections.Generic; 使用System.Linq; 使用系统文本

命名空间控制台40 { LinqFlatten类 {


}

此处的最终目标是什么?似乎是覆盖。ToString是您真正想要的。将每个客户和关联列表展平到列表中的一个记录中,展平记录的类型应该是什么?还要定义信用卡和地址类的结构此处的最终目标是什么?似乎是覆盖。ToString是您真正想要的t、 将每个客户和相关列表展平为列表中的一条记录展平记录的类型是什么?还要定义信用卡的结构和地址classUnion为您提供了联合集。您可能不希望也不需要联合的开销。Concat可能是您想要的。@BAF,谢谢,您是对的。当然对问题进行编辑使我的答案不再适用,但与最初提出的答案相同。:-Union为您提供Union集合。您可能不想要也不需要Union的开销。Concat可能是您想要的。@BAF,谢谢,您是对的。当然,对问题进行编辑使我的答案不再适用,但它执行的是原始设置ally问道:-@BAF-正是我想要的,谢谢你。Samual-这也很好,我也很感谢你提供的源代码。我选择BAF只是因为我更喜欢lambda语法。Kendall-这个解决方案也可以。谢谢你分享。L.B我是一个盲人程序员,所以没有看到我在编辑后忘了编辑代码。所以谢谢。如果有兴趣的话,谷歌屏幕阅读器,在维基百科上阅读我是怎么做的。我的第一篇文章是按ctrl+k来格式化的。我想编辑操作会保留我的初始缩进。@BAF-正是我想要的谢谢你。Samual-这也很好,我很感谢你提供的源代码。我选择了BAF sim因为我更喜欢lambda语法。Kendall-这个解决方案也可以。谢谢分享。L.B我是一个盲人程序员,所以没有看到我在编辑后忘了编辑代码。对此很抱歉。如果有兴趣,谷歌屏幕阅读器和维基百科上阅读我是如何做的。我的第一篇帖子是按ctrl+k格式化的。我我以为编辑操作会保留我的初始缩进。@Samuel Edited,我忘了a。Select,我希望您用要显示的属性名称替换CardName。@Samuel Edited,我忘了a。Select,我希望您用要显示的属性名称替换CardName。