我有兩個物件串列,它們具有一個名為 OrderNumber 的公共屬性。
第一個串列有大約 20000 個專案,第二個串列有大約 150 萬個專案。
我需要一種有效的方法來從串列 1 中查找串列 2 中沒有匹配項的專案。我目前正在使用 Linq,計算解決方案需要 20 多分鐘。我無法在網上找到有效的解決方案。
到目前為止我的代碼
notmatched.AddRange(List1.Where(l1=> !list2.Select(l2=> l2.OrderNumber).Contains(l1.OrderNumber)).Select(l1 => new SomeObj
{
OrderNumber = l1.OrderNumber
}));
uj5u.com熱心網友回復:
使用 Linq 提供的內置 except 擴展足夠快,提供自定義 IEqualityComparer。我的實作可能不適用于您的用例,但在 firstList 中有 150 萬個 Poco 類,在 secondList 中有 20k 個,它在 1 秒內執行。
IEqualityComparer的檔案,Linq 除外
DotnetFiddle - 減少數字以解決記憶體限制
// Classes used in test:
public interface IOrderNumber
{
string OrderNumber { get; set; }
}
public class Poco: IOrderNumber
{
public string OrderNumber { get; set; }
}
public class Podo: IOrderNumber
{
public string OrderNumber {get;set;}
}
public class DataEqualityComparer : IEqualityComparer<IOrderNumber>
{
public bool Equals(IOrderNumber p1, IOrderNumber p2)
{
var equal = GetHashCode(p1) == GetHashCode(p2);
return equal;
}
public int GetHashCode(IOrderNumber p1)
{
if (p1 == null)
return -1;
int hCode = p1.OrderNumber.GetHashCode();
return hCode.GetHashCode();
}
}
... then your code would look like this:
var firstList = Enumerable.Range(1, 1500000).Select(x => new Poco { OrderNumber = x.ToString() }).ToList();
var secondList = Enumerable.Range(50, 20000).Select(x => new Podo { OrderNumber = x.ToString() }).ToList();
Stopwatch sw = Stopwatch.StartNew();
var result = firstList.Except(secondList, new DataEqualityComparer()).ToList();
sw.Stop();
Console.WriteLine($"Duration: {sw.Elapsed:G}");
uj5u.com熱心網友回復:
這是您的解決方案的更簡化版本,它使用更少的回圈來完成這項作業,但我不確定這是否會使程序更快,如果可以,請告訴我
notmatched.AddRange(List1.Where(l1=> !list2.Any(l2=> l2.OrderNumber == l1.OrderNumber).Select(l1 => new SomeObj
{
OrderNumber = l1.OrderNumber
}));
uj5u.com熱心網友回復:
使用 LinqExcept比較物件。您必須為復雜物件實作一個 IEquatable 介面。
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public static void Main()
{
var first = new List<Poco> { new Poco {OrderNumber = "test", Orderid = 1 }, new Poco {OrderNumber = "test", Orderid = 1 } };
var second = new List<Poco> { new Poco {OrderNumber = "test", Orderid = 1 }, new Poco {OrderNumber = "test", Orderid = 1 } };
first.Except(second).Dump();
second.Except(first).Dump();
if ( !first.Except(second).Any() && !second.Except(first).Any())
{
Console.Write("first and second are equal");
} else {
Console.Write("equality failed");
}
}
}
public class Poco : IEquatable<Poco>
{
public string OrderNumber { get; set; }
public int Orderid {get; set;}
public bool Equals(Poco other)
{
if (other == null )
return false;
return this.Orderid == other.Orderid && this.OrderNumber == other.OrderNumber;
}
public override bool Equals(Object obj)
{
if (obj == null)
return false;
Poco poco = obj as Poco;
if (poco == null)
return false;
else
return Equals(obj);
}
public override int GetHashCode() => (Orderid, OrderNumber).GetHashCode();
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/523880.html
標籤:C#。网算法
