[英]Pad the left or right sides of a linq join to be the same number of rows
我的目标是创建一个与右侧或左侧相同行数的列表,而不管左列或右列是否比另一列短。
考虑这两个查询:
var result1 = (from f in list2
join b in list1 on f.index equals b.index into bf
from x in bf.DefaultIfEmpty()
select new { box = (x == null ? String.Empty : x.b), file = f.f });
var result2 = (from b in list1
join f in list2 on b.index equals f.index into bf
from x in bf.DefaultIfEmpty()
select new { l1 = x.f, l2 = (x == null ? String.Empty : b.b) });
一个在list1上测试null并填充一个空字符串,另一个在list2上测试null并填充一个空字符串。
我想找一个两者都可能发生的例子。 顺序并不重要,只是左边的每个值或空字符串都有一个值或右边的空字符串。
看起来你需要一个IEnumerable.Zip
扩展方法的版本,当较短的列表到达它的末尾时它不会停止:
public static IEnumerable<TResult> ZipAll<T, TResult>(this IEnumerable<T> list1,
IEnumerable<T> list2,
Func<T, T, TResult> zipper,
T defaultValue = default(T))
{
using (var enum1 = list1.GetEnumerator())
{
using (var enum2 = list2.GetEnumerator())
{
bool valid1, valid2;
do
{
valid1 = enum1.MoveNext();
valid2 = enum2.MoveNext();
if (valid1 || valid2)
{
var item1 = valid1 ? enum1.Current : defaultValue;
var item2 = valid2 ? enum2.Current : defaultValue;
yield return zipper(item1, item2);
}
}
while (valid1 || valid2);
}
}
}
..然后:
var result = list1.ZipAll(list2, (l1, l2) => new { l1, l2 }, string.Empty);
如果我理解你的问题,那么你几乎就在你想要的地方:
扩展代码:
var result= (from f in list2
join b in list1 on f.index equals b.index into bf
from x in bf.DefaultIfEmpty()
select new { l1 = (x == null ? String.Empty : x.b), l2 = f.f })
.ToList().Select(li => new List<List<string>>
{
new List<string>
{
li.l1,
li.l2
}
}).ToList()
.SelectMany (li => li).ToList();
这给List包含了这样的字符串对象列表:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.