首页 > 解决方案 > Linq 从 2 个差异列表加入

问题描述

我有A类如下

class A {
 int id,
 string state,
 string name
}

和 2 列表

List<A> l1;

A (1, "S1", "N1")
A (2, "S2", "")
A (3, "S3", "N3")
A (4, "S4", "N4")

List<A> l2;
A (11, "S2", "N21")
A (12, "S2", "N22")

现在我想要这样的期望 l1 结果,它看起来像左连接,如果“名称为空”,则将 l1 中的空值替换为 l2 中的值。

A (1, "S1", "N1")
A (11, "S2", "N21")
A (12, "S2", "N22")
A (3, "S3", "N3")
A (4, "S4", "N4")

我尝试获取内部连接和 l1.add(inner_join_results) 的结果,但它也包含空值。感谢任何帮助或建议

标签: c#linq

解决方案


使用我已经拥有的一些扩展方法:

public static bool IsEmpty(this string s) => (s.Length == 0);
public static bool IsNotEmpty(this string s) => (s.Length > 0);
public static IEnumerable<T> AsSingleton<T>(this T item) => new[] { item };

您可以按空名称过滤列表:

var ans = l1.SelectMany(anL => anL.name.IsNotEmpty()
                                    ? anL.AsSingleton()
                                    : l2.Where(anL2 => anL2.state == anL.state))
            .ToList();

或者,更高效的是编写一个自定义扩展:

public static IEnumerable<T> Replace<T>(this IEnumerable<T> src, Func<T,bool> testFn, Func<T,IEnumerable<T>> replFn) {
    foreach (var e in src) {
        if (testFn(e))
            foreach (var e2 in replFn(e))
                yield return e2;
        else
            yield return e;
    }
    
}

那么你的答案是:

var ans2 = l1.Replace(anL => anL.name.IsEmpty(), anL => l2.Where(anL2 => anL.state == anL2.state)).ToList();

推荐阅读