我有
List<X> A = new List<X>{null,"1",null,"3"};
List<Y> B = new List<Y>{ 0 , 1 , 2 , 3 };
我想使用linq仅列出B中的元素,这些元素在A中具有非空的对应值。所以...
List<Y> C = [some linq expression using A and B];
C现在有1和3。
如何做到这一点?
答案 0 :(得分:4)
List<String> A = new List<String> { null, "1", null, "3" };
List<int> B = new List<int> { 0, 1, 2, 3 };
var C = A.Zip(B, (s, n) => new { a = s, b = n })
.Where(x => x.a != null)
.Select(x => x.b)
.ToList();
答案 1 :(得分:3)
var c = B.Where((o, i) => A[i] != null).ToList();
答案 2 :(得分:2)
编辑注意到我写不清楚这两个列表是否按索引对齐。鉴于该信息,不确定此响应的价值。它的价值肯定低于我最初的想象。
基本上你想要的是一个交集。以下是使用Intersect()的答案,它基于示例中提供的数据和参数工作:
var a = new List<string> { null, "1", null, "3" };
var b = new List<int> { 0, 1, 2, 3 };
var intersection = a.Intersect(b.Select(x => x.ToString())).ToList();
您应该能够适应适合您的交叉路口。
如果你的两个列表中都有可以为空的项目,那么你需要对b列表进行额外的空值检查(我只是盲目地在其中的每个项目上调用ToString())。但是如果B不包含空值并且你正在进行交集,那么就没有理由在A中过滤掉空值,它们将作为该过程的一部分被过滤掉。
还要考虑:
b.Select(x => x.ToString()) ...
非常容易:
b.Select(x => ConvertTypeBToTypeA(x)) ...
答案 3 :(得分:1)
List<string> A = new List<string> { null, "1", null, "3" };
List<int> B = new List<int> { 0, 1, 2, 3 };
var C = B.Where(x => A.Contains(x.ToString()));
答案 4 :(得分:0)
试试这个:
var c = Enumerable.Range(0, Math.Min(B.Count, A.Count))
.Where(i => A[i] != null)
.Select(i => B[i]).ToList();
答案 5 :(得分:0)
扩展方法如何避免一些开销?
<PropertyGroup>
创建后,您可以使用
<DisableImplicitFrameworkReferences>true</DisableImplicitFrameworkReferences>
您可能还需要一个Microsoft.NETCore.App
变体,但创建一个变体并不容易。
我想你可以作弊并返回一个适用public static class Ext {
public static IEnumerable<T1> WhereOther<T1, T2>(this IEnumerable<T1> src, IEnumerable<T2> filter, Func<T2, bool> pred) {
using (var isrc = src.GetEnumerator())
using (var ifilter = filter.GetEnumerator())
while (ifilter.MoveNext())
if (isrc.MoveNext())
if (pred(ifilter.Current))
yield return isrc.Current;
}
}
然后使用var ans = B.WhereOther(A, p => p != null);
的lambda。