C#list数据替换,字典和linq比较

C#问题:有两个list集合,list1和list2的dto中jhrq和sccj字段一样时,将list2中yssah赋值给list1

在C#中,如果你有两个列表(我们假设它们是List<SomeDto>类型,其中SomeDto是一个包含jhrqsccjyssah等字段的DTO类),并且你想根据jhrqsccj字段的匹配来更新list1中的yssah字段值,你可以使用LINQ(Language Integrated Query)来实现这个操作。

以下是一个简单的示例,展示了如何实现这个需求:

首先,定义你的DTO类(如果还没有的话):

public class SomeDto  
{  
    public string jhrq { get; set; }  
    public string sccj { get; set; }  
    public string yssah { get; set; }  
    // 可能还有其他字段和属性...  
}

然后,你可以使用LINQ的Join方法(或者ForEachAny的组合)来更新list1中的yssah字段:

使用Join方法的示例:

var query = from dto1 in list1  
            join dto2 in list2 on new { dto1.jhrq, dto1.sccj } equals new { dto2.jhrq, dto2.sccj }  
            select new { dto1, dto2 };  
  
foreach (var item in query)  
{  
    item.dto1.yssah = item.dto2.yssah; // 更新list1中的yssah字段  
}

或者使用ForEachAny的组合(如果不需要创建匿名类型的实例):

list1.ForEach(dto1 =>  
{  
    var matchingDto2 = list2.FirstOrDefault(dto2 => dto2.jhrq == dto1.jhrq && dto2.sccj == dto1.sccj);  
    if (matchingDto2 != null)  
    {  
        dto1.yssah = matchingDto2.yssah; // 更新list1中的yssah字段  
    }  
});
 
 

在这个例子中,我们遍历list1中的每个DTO,并使用LINQ的FirstOrDefault方法来查找list2中匹配的DTO。如果找到了匹配的DTO,我们就更新list1中当前DTO的yssah字段值。注意,这种方法的时间复杂度是O(n*m),其中n是list1的长度,m是list2的长度。如果列表很大,可能需要考虑优化性能。

你也可以使用字典(Dictionary<TKey, TValue>)来优化查找性能,尤其是当list2很大时。通过将list2转换为一个字典,你可以将查找时间从O(n)降低到接近O(1)(在平均情况下)。

以下是一个示例,展示如何使用字典来根据jhrqsccj字段更新list1中的yssah字段:

// 假设SomeDto是你的DTO类,它包含jhrq, sccj, yssah等字段  
List<SomeDto> list1 = ...; // 你的第一个列表  
List<SomeDto> list2 = ...; // 你的第二个列表  
  
// 创建一个字典,键是(jhrq, sccj)的组合,值是yssah  
var dict = list2.ToDictionary(dto => new { dto.jhrq, dto.sccj }, dto => dto.yssah);  
  
// 遍历list1并更新yssah字段(如果字典中存在匹配的键)  
foreach (var dto1 in list1)  
{  
    var key = new { dto1.jhrq, dto1.sccj }; // 创建一个与dict键相同类型的匿名对象  
    if (dict.TryGetValue(key, out string yssahValue)) // 尝试从字典中获取yssah值  
    {  
        dto1.yssah = yssahValue; // 更新list1中的yssah字段  
    }  
}
然而,请注意,由于字典的键是引用类型(在这个例子中是匿名类型的实例),你需要确保用于创建字典键的匿名类型实例与在list1迭代中创建的实例在结构上完全相同(即它们必须是同一个匿名类型的实例,并且所有属性都相等)。

为了避免使用匿名类型作为字典的键(因为匿名类型通常不应在方法外部使用,并且它们的相等性比较可能不是你所期望的),你可以创建一个简单的类来封装jhrqsccj字段,并重写EqualsGetHashCode方法,以便正确地比较这些字段:

public class DtoKey  
{  
    public string Jhrq { get; }  
    public string Sccj { get; }  
  
    public DtoKey(string jhrq, string sccj)  
    {  
        Jhrq = jhrq;  
        Sccj = sccj;  
    }  
  
    // 重写Equals和GetHashCode方法以支持字典查找  
    // ...  
}  
  
// 然后,在创建字典和查找时使用DtoKey类而不是匿名类型


这样,你就可以安全地在方法外部使用DtoKey类,并且字典的查找将基于你定义的EqualsGetHashCode方法的实现。

下面分析这三种方法的时间复杂度

在使用字典(Dictionary<TKey, TValue>)和上面提到的两个例子(LINQ Join 和 ForEach + Any)时,我们可以分析它们的时间复杂度。

使用字典

当你使用字典来优化查找性能时,你可以将list2转换为一个字典,其中键是(jhrq, sccj)的组合,值是yssah。这个过程的时间复杂度是O(n),其中n是list2的长度,因为你需要遍历整个列表来填充字典。

一旦字典被创建,遍历list1并更新yssah字段的时间复杂度是O(m),其中m是list1的长度。因为字典查找的平均时间复杂度是O(1),所以整个更新过程的时间复杂度是O(m)。

因此,总的时间复杂度是O(n) + O(m),但由于我们通常只关注主要项(即增长最快的项),并且在这里n和m可能不是同一数量级,所以我们通常会说是O(n + m),但在实际场景中,如果m远大于n,我们可能会简化为O(m)。

使用LINQ Join

使用LINQ Join时,你需要遍历list1中的每个元素,并对每个元素在list2中进行搜索。这个过程的时间复杂度是O(n * m),其中n是list1的长度,m是list2的长度。这是因为对于list1中的每个元素,你都可能需要遍历整个list2来找到匹配项。

使用ForEach + Any

ForEach + Any 的方法与LINQ Join在本质上相似。对于list1中的每个元素,你都在list2中执行一次Any操作来查找匹配项。Any操作可能需要遍历list2中的部分或全部元素,因此平均时间复杂度也是O(m)(对于list2中的每个元素)。所以总的时间复杂度同样是O(n * m),其中n是list1的长度,m是list2的长度。

总结

  • 使用字典:O(n + m),但通常简化为O(max(n, m))
  • 使用LINQ Join:O(n * m)
  • 使用ForEach + Any:O(n * m)

在大多数情况下,使用字典的方法将比使用LINQ Join或ForEach + Any的方法更快,特别是当list2(即字典)很大时。这是因为字典提供了接近O(1)的查找时间,而LINQ Join和ForEach + Any则需要遍历整个list2来查找匹配项。

  • 10
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值