首页 > 其他分享 >使用LINQ、Lambda 表达式 、委托快速比较两个集合,找出需要新增、修改、删除的对象

使用LINQ、Lambda 表达式 、委托快速比较两个集合,找出需要新增、修改、删除的对象

时间:2024-01-21 20:24:15浏览次数:37  
标签:target List LINQ source Func var 集合 表达式 Lambda

快速对比两个list数据集合

此文引用csdn :https://blog.csdn.net/Zhu_daye/article/details/104798410

小批量、快速对比两个list数据集合

using System.Linq.Expressions;

Main();
void Main()
{
    // 对比源集合
    var source = GenerateStudent(1, 10000, 1000);
    // 目标集合
    var target = GenerateStudent(5000, 10000, 1000);
    //Expression<>
    // 唯一标识比较
    Func<Student, Student, bool> keyCompartor = (s, t) => s.Id == t.Id;
    // 实体相等比较
    Func<Student, Student, bool> entityCompartor = (s, t) => s.Id == t.Id && s.Name.Equals(t.Name) && s.Age == t.Age;

    // 新增前准备
    Func<Student, Student> insertAction = (s) =>
    {
        return new Student
        {
            Id = s.Id,
            Name = s.Name,
            Age = s.Age,
            Operation = "Insert"
        };
    };

    // 更新前准备
    Func<Student, Student, Student> updateAction = (s, t) =>
    {
        t.Name = s.Name;
        t.Age = s.Age;
        t.Operation = "Update";

        return t;
    };

    // 删除前准备
    Func<Student, Student> deleteAction = (t) =>
    {
        t.Operation = "Delete";
        return t;
    };

    // 去掉相等对象
    RemoveDuplicate(source, target, entityCompartor, (s1, s2) => s1.Id == s2.Id, keyCompartor);

    // 需要新增的集合
    var insertingStudents = GetInsertingEntities(source, target, keyCompartor, insertAction);
    // 需要更新的集合
    var updatingStudents = GetUpdatingEntities(source, target, keyCompartor, entityCompartor, updateAction);
    // 需要删除的集合
    var deletingStudents = GetDeletingEntities(source, target, keyCompartor, deleteAction);

    // 后续业务
    // InsertStudents(insertingStudents);
    // UpdateStudents(updatingStudents);
    // DeleteStudents(deletingStudents);

    Console.WriteLine("");
    // 集合去重
    void RemoveDuplicate<S, T>(List<S> source, List<T> target, Func<S, T, bool> entityCompartor,
       Func<S, S, bool> sourceKeyCompartor, Func<S, T, bool> keyComportor)
    {
        var sameEntities = source.Where(s => target.Exists(t => entityCompartor(s, t))).ToList();
        source.RemoveAll(s => sameEntities.Exists(s2 => sourceKeyCompartor(s, s2)));
        target.RemoveAll(t => sameEntities.Exists(s => keyComportor(s, t)));
    }

    // 获取需要新增的对象集合
    List<T> GetInsertingEntities<S, T>(List<S> source, List<T> target, Func<S, T, bool> keyComportor,
       Func<S, T> insertAction)
    {
        var result = new List<T>();
        foreach (var s in source)
        {
            var t = target.FirstOrDefault(x => keyComportor(s, x));
            if (t == null)
            {
                // 目标集合中不存在,则新增
                result.Add(insertAction(s));
            }
        }

        return result;
    }

    // 获取需要更新的对象集合
    List<T> GetUpdatingEntities<S, T>(List<S> source, List<T> target, Func<S, T, bool> keyComportor,
       Func<S, T, bool> entityCompartor, Func<S, T, T> updateAction)
    {
        var result = new List<T>();
        foreach (var s in source)
        {
            var t = target.FirstOrDefault(x => keyComportor(s, x));
            if (t != null && !entityCompartor(s, t))
            {
                // 目标集合中存在,但是次要属性不相等,则更新
                result.Add(updateAction(s, t));
            }
        }

        return result;
    }

    // 获取需要删除的对象集合
    List<T> GetDeletingEntities<S, T>(List<S> source, List<T> target,
       Func<S, T, bool> keyComportor, Func<T, T> deleteAction)
    {
        var result = new List<T>();
        foreach (var t in target)
        {
            var s = source.FirstOrDefault(x => keyComportor(x, t));
            if (s == null)
            {
                // 源集合中存在,目标集合中需要删除
                result.Add(deleteAction(t));
            }
        }

        return result;
    }

    // 随机生成测试集合
    List<Student> GenerateStudent(int minId, int maxId, int maxNumber)
    {
        var r = new Random();
        var students = new List<Student>();
        for (int i = 0; i < maxNumber; i++)
        {
            students.Add(new Student
            {
                Id = r.Next(minId, maxId),
                Name = $"name: {r.Next(1, 10)}",
                Age = r.Next(6, 10)
            });
        }

        return students.GroupBy(s => s.Id).Select(s => s.First()).ToList();
    }
}
public class Student
{
    public int Id { get; set; }

    public string Name { get; set; }

    public int Age { get; set; }

    public string Operation { get; set; }
}

小数量数据 推荐使用linq 以下方法

点击查看代码
List<SRModel> SRlist= db.SRModels.ToList();
 List<SRUserInfoDto> Userlist = DataProcessing();
 //对比两个集合中的差异并出来。两种方法取。
var srGorup = Userlist.Where(x => !SRlist.Any(a => x.XiaoShouDaiBiaoBianMa == a.XiaoShouDaiBiaoBianMa)).ToList();  
 var intolist = Userlist.Where(a => !SRlist.Select(b => b.XiaoShouDaiBiaoBianMa).Contains(a.XiaoShouDaiBiaoBianMa)).ToList

标签:target,List,LINQ,source,Func,var,集合,表达式,Lambda
From: https://www.cnblogs.com/Bo-H/p/17978266

相关文章

  • js 立即执行函数表达式
    如果没有函数名,当函数需要引用自身时只能使用已经过期的arguments.callee引用,比如在递归中。另一个函数需要引用自身的例子,是在事件触发后事件监听器需要解绑自身。匿名函数省略了对于代码可读性/可理解性很重要的函数名。一个描述性的名称可以让代码不言自明。行内函数表达式......
  • 代码随想录算法训练营第 十 一 天| 20. 有效的括号 1047. 删除字符串中的所有相邻重
    LeetCode 20.有效的括号题目链接:20.有效的括号思路:采用栈数据结构解题;遇到左括号,压右括号入栈 LeetCode 1047.删除字符串中的所有相邻重复项题目链接:1047.删除字符串中的所有相邻重复项注意:Java中队列实现类API的使用 LeetCode 150.逆波兰表达式求值题目链......
  • 逆波兰表达式求值
      /**@lcapp=leetcode.cnid=150lang=cpp**[150]逆波兰表达式求值*///@lccode=startclassSolution{public:intcalc(intleft,intright,charsign){switch(sign){case'+':returnleft+ri......
  • 细说JavaScript表达式和运算符号(JavaScript表达式和运算符号详解)
    除了简单的表达式还有复杂的表达式,它是由简单表达式构成的,将简单表达式组合成复杂表达式最常见的方法就是使用运算符![细说JavaScript表达式和运算符号详解](https://img-blog.csdnimg.cn/direct/2781400b25be4b38bbf99d0c1b93d169.png)一、表达式表达式分为简单表达式和复杂......
  • 使用Cron表达式调度多个任务的实现方法
    Cron表达式是一种用于指定定时任务执行时间的字符串格式。通过合理运用Cron表达式,我们可以方便地调度多个任务,并按照设定的时间规则自动执行。本文将介绍如何使用Cron表达式来调度多个任务,以帮助您更好地管理和执行定时任务。一、什么是Cron表达式Cron表达式是一种由6个或7个字段组......
  • 开源:Taurus.DTS 微服务分布式任务框架,支持即时任务、延时任务、Cron表达式定时任务和
    前言:在发布完:开源:Taurus.DTC微服务分布式事务框架,支持.Net和.NetCore双系列版本,之后想想,好像除了事务外,感觉里面多了一个任务发布订阅的基础功能。本想既然都有了基础发布订阅功能了,那要不要顺带加上延时发布功能呢?加上了会不会让事务组件不纯了?经过一翻深思,是在其上补上......
  • 无涯教程-SQLite - 表达式
    SQL表达式类似于公式,它们以查询语言编写,您还可以用于向数据库查询一组特定的数据。Expressions-语法考虑一下SELECT语句的基本语法,如下所示:SELECTcolumn1,column2,columnNFROMtable_nameWHERE[CONDITION|EXPRESSION];以下是不同类型的SQLite表达式。Expressio......
  • DevExpress Web Report Designer中文教程 - 如何自定义控件和表达式注册?
    获取DevExpressv23.2正式版下载DevExpress技术交流群9:909157416      欢迎一起进群讨论自定义控件集成DevExpress Reports中的自定义报表控件注册变得更加容易,为了满足web开发人员的需求,DevExpressv23.1+包括简化的自定义控件注册支持(在服务器级别实现)。如果您的解决......
  • 正则表达式复习七——JavaScript 中使用
    JavaScript使用JavaScript的正则表达式是由RegExp对象表示的,同时也可以使用正则表达式字面量。1.使用RegExp对象letpattern=newRegExp("pattern","flags");pattern是字符串形式的正则表达式模式。flags是字符串形式的修饰符,可以包含i,g,m等。letpattern......
  • 正则表达式
    正则表达式匹配符d?d出现0/1次a*a可以出现0/多次a+a出现一次以上a{6}a出现6次a{2,}a出现2次以上a{2,6}a出现2-6次匹配多个字符:(ab)+ab出现一次以上或运算a(cat|dog)匹配acatoradogacat|dog匹配acatordog字符类匹配由abc构成的数据【abc】+abc出现一次......