我需要将父列表和两个子列表压缩到一个列表中。我怎么能用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列表和地址列表变平。
感谢您的反馈!
答案 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"
}
}
}
};
}
}
}