/// <summary> /// 两列表数据相同(包含两列表重复数据的数量都一样) /// </summary> /// <typeparam name="TLeft"></typeparam> /// <typeparam name="TRight"></typeparam> /// <typeparam name="TEquals"></typeparam> /// <param name="param"></param> /// <param name="isBigData">是否是处理大数据</param> /// <returns></returns> public static bool IsEquals <TLeft, TRight, TEquals>(ListComparerParam <TLeft, TRight, TEquals> param, bool isBigData) { if (param.LeftList.Count() != param.RightList.Count()) { return(false); } if (isBigData) { param = RemoveSameOneRecord(param); } // 分组对比数据 var lefts = param.LeftList.GroupBy(param.LeftFunc.Invoke).Select(p => new ListEquals <TEquals>() { Obj = p.Key, Total = p.Count() }).ToList(); var rights = param.RightList.GroupBy(param.RightFunc.Invoke).Select(p => new ListEquals <TEquals>() { Obj = p.Key, Total = p.Count() }).ToList(); if (lefts.Count != rights.Count) { return(false); } var count = lefts.Join(rights, p => p.Obj, p => p.Obj, (p, q) => new { p, q }).Count(p => p.p.Total == p.q.Total); if (count != lefts.Count) { return(false); } return(true); }
/// <summary> /// 移除两边都是一条记录的数据 /// </summary> /// <typeparam name="TLeft"></typeparam> /// <typeparam name="TRight"></typeparam> /// <typeparam name="TEquals"></typeparam> /// <param name="param"></param> /// <returns></returns> public static ListComparerParam <TLeft, TRight, TEquals> RemoveSameOneRecord <TLeft, TRight, TEquals>(ListComparerParam <TLeft, TRight, TEquals> param) { var leftDict = new Dictionary <TEquals, TLeft>(); var leftRepeat = new List <TLeft>(); foreach (var item in param.LeftList) { var key = param.LeftFunc.Invoke(item); if (!leftDict.ContainsKey(key)) { leftDict.Add(key, item); } else { leftRepeat.Add(item); } } var rightDict = new Dictionary <TEquals, TRight>(); var rightRepeat = new List <TRight>(); foreach (var item in param.RightList) { var key = param.RightFunc.Invoke(item); if (!rightDict.ContainsKey(key)) { rightDict.Add(key, item); } else { rightRepeat.Add(item); } } //重复的数据 var repeats = leftRepeat.Select(param.LeftFunc.Invoke).Union(rightRepeat.Select(param.RightFunc.Invoke)).ToList(); //左1右0 var leftHas = new Dictionary <TEquals, TLeft>(); foreach (var item in leftDict) { if (!rightDict.ContainsKey(item.Key)) { leftHas.Add(item.Key, item.Value); } } //左0右1 var rightHas = new Dictionary <TEquals, TRight>(); foreach (var item in rightDict) { if (!leftDict.ContainsKey(item.Key)) { rightHas.Add(item.Key, item.Value); } } //左边不同数据都取出来 var listLeft = new List <TLeft>(); listLeft.AddRange(leftRepeat); foreach (var key in repeats) { if (leftDict.ContainsKey(key)) { listLeft.Add(leftDict[key]); } } foreach (var item in leftHas.GroupJoin(repeats, p => p.Key, p => p, (p, q) => new { p, q }).Where(p => !p.q.Any()).Select(m => m.p).ToList()) { listLeft.Add(leftDict[item.Key]); } //右边不同数据都取出来 var listRight = new List <TRight>(); listRight.AddRange(rightRepeat); foreach (var key in repeats) { if (rightDict.ContainsKey(key)) { listRight.Add(rightDict[key]); } } foreach (var item in rightHas.GroupJoin(repeats, p => p.Key, p => p, (p, q) => new { p, q }).Where(p => !p.q.Any()).Select(m => m.p).ToList()) { listRight.Add(rightDict[item.Key]); } param.LeftList = listLeft; param.RightList = listRight; return(param); }
/// <summary> /// 返回两列表差异数据集合(包含重复数据的数量对比) /// </summary> /// <typeparam name="TLeft"></typeparam> /// <typeparam name="TRight"></typeparam> /// <typeparam name="TEquals"></typeparam> /// <param name="param"></param> /// <param name="isBigData">是否是处理大数据</param> public static ListDiffResult <TLeft, TRight, TEquals> GetDiffList <TLeft, TRight, TEquals>(ListComparerParam <TLeft, TRight, TEquals> param, bool isBigData) { if (isBigData) { param = RemoveSameOneRecord(param); } var lefts = param.LeftList.GroupJoin(param.RightList, param.LeftFunc.Invoke, param.RightFunc.Invoke, (p, q) => new { p, q }).Where(p => p.q.Count() != 1).ToList(); var rights = param.RightList.GroupJoin(param.LeftList, param.RightFunc.Invoke, param.LeftFunc.Invoke, (p, q) => new { p, q }).Where(p => p.q.Count() != 1).ToList(); var ls = lefts.Where(p => p.q.Count() > 1) .GroupBy(p => param.LeftFunc.Invoke(p.p), (p, q) => new { p, q }) .Select(m => new ListRepeatResult <TLeft, TRight, TEquals> { Object = m.p, Lefts = m.q.Select(p => p.p).ToList(), Rights = m.q.First().q.ToList() }) .Where(p => p.Lefts.Count != p.Rights.Count); var rs = rights.Where(p => p.q.Count() > 1) .GroupBy(p => param.RightFunc.Invoke(p.p), (p, q) => new { p, q }) .Select(m => new ListRepeatResult <TLeft, TRight, TEquals> { Object = m.p, Lefts = m.q.First().q.ToList(), Rights = m.q.Select(p => p.p).ToList() }) .Where(p => p.Lefts.Count != p.Rights.Count); var result = new ListDiffResult <TLeft, TRight, TEquals> { LeftDiffs = lefts.Where(p => !p.q.Any()).Select(p => p.p).ToList(), RightDiffs = rights.Where(p => !p.q.Any()).Select(p => p.p).ToList(), Repeats = ls.Union(rs).ToList() }; return(result); }
/// <summary> /// 移除两边都是一条记录的数据 /// </summary> /// <typeparam name="TLeft"></typeparam> /// <typeparam name="TRight"></typeparam> /// <typeparam name="TEquals"></typeparam> /// <param name="leftList"></param> /// <param name="rightList"></param> /// <param name="leftFunc"></param> /// <param name="rightFunc"></param> /// <returns></returns> public static ListComparerParam <TLeft, TRight, TEquals> RemoveSameOneRecord <TLeft, TRight, TEquals>(this IEnumerable <TLeft> leftList, IEnumerable <TRight> rightList, Func <TLeft, TEquals> leftFunc, Func <TRight, TEquals> rightFunc) { var param = new ListComparerParam <TLeft, TRight, TEquals>(leftList, rightList, leftFunc, rightFunc); return(ListHelper.RemoveSameOneRecord(param)); }
/// <summary> /// 返回两列表差异数据集合(包含重复数据的数量对比) /// </summary> /// <typeparam name="TLeft"></typeparam> /// <typeparam name="TRight"></typeparam> /// <typeparam name="TEquals"></typeparam> /// <param name="leftList"></param> /// <param name="rightList"></param> /// <param name="leftFunc"></param> /// <param name="rightFunc"></param> /// <param name="isBigData">是否是处理大数据</param> /// <returns></returns> public static ListDiffResult <TLeft, TRight, TEquals> GetDiffList <TLeft, TRight, TEquals>(this IEnumerable <TLeft> leftList, IEnumerable <TRight> rightList, Func <TLeft, TEquals> leftFunc, Func <TRight, TEquals> rightFunc, bool isBigData) { var param = new ListComparerParam <TLeft, TRight, TEquals>(leftList, rightList, leftFunc, rightFunc); return(ListHelper.GetDiffList(param, isBigData)); }