私は2つのリストを持っています
List<Sent> SentList;
List<Messages> MsgList;
どちらもMsgIDと呼ばれる同じプロパティを持っています。
MsgList SentList
MsgID Content MsgID Content Stauts
1 aaa 1 aaa 0
2 bbb 3 ccc 0
3 ccc
4 ddd
5 eee
msglistのMsgIDをsentlistと比較し、linqを使用して送信済みリストにないアイテムが必要な場合
Result
MsgID Content
2 bbb
4 ddd
5 eee
次のようなことができます:
HashSet<int> sentIDs = new HashSet<int>(SentList.Select(s => s.MsgID));
var results = MsgList.Where(m => !sentIDs.Contains(m.MsgID));
これにより、MsgList
に一致するIDがないSentList
のすべてのメッセージが返されます。
素朴なアプローチ:
MsgList.Where(x => !SentList.Any(y => y.MsgID == x.MsgID))
これにはm*n
は、MsgID
のすべてのSentList
をMsgList
の各_($ var)_(「まで」と比較するときの動作です。なぜならdoes一致する)。
さて、あなたはすでに良い答えを持っていますが、それらはほとんどのラムダです。よりLINQのアプローチは次のようになります
var NotSentMessages =
from msg in MsgList
where !SentList.Any(x => x.MsgID == msg.MsgID)
select msg;
次のようなことができます
var notSent = MsgSent.Except(MsgList, MsgIdEqualityComparer);
MSDNで概説されているように、カスタムの等値比較子を提供する必要があります。
http://msdn.Microsoft.com/en-us/library/bb336390.aspx
それぞれのタイプのMsgIDプロパティでのみ、その等価比較子ベースの等価性を持っているだけです。等値比較器は同じ型の2つのインスタンスを比較するため、SentとMessagesMsgIDプロパティを持つ実装。
このようにすることができます、これは最も速いプロセスです
Var result = MsgList.Except(MsgList.Where(o => SentList.Select(s => s.MsgID).ToList().Contains(o.MsgID))).ToList();
これにより、期待どおりの出力が得られます。
試して、
public class Sent
{
public int MsgID;
public string Content;
public int Status;
}
public class Messages
{
public int MsgID;
public string Content;
}
List<Sent> SentList = new List<Sent>() { new Sent() { MsgID = 1, Content = "aaa", Status = 0 }, new Sent() { MsgID = 3, Content = "ccc", Status = 0 } };
List<Messages> MsgList = new List<Messages>() { new Messages() { MsgID = 1, Content = "aaa" }, new Messages() { MsgID = 2, Content = "bbb" }, new Messages() { MsgID = 3, Content = "ccc" }, new Messages() { MsgID = 4, Content = "ddd" }, new Messages() { MsgID = 5, Content = "eee" }};
int [] sentMsgIDs = SentList.Select(v => v.MsgID).ToArray();
List<Messages> result1 = MsgList.Where(o => !sentMsgIDs.Contains(o.MsgID)).ToList<Messages>();
それが役立つことを願っています。
List<Car> cars = new List<Car>() { new Car() { Name = "Ford", Year = 1892, Website = "www.ford.us" },
new Car() { Name = "Jaguar", Year = 1892, Website = "www.jaguar.co.uk" },
new Car() { Name = "Honda", Year = 1892, Website = "www.honda.jp"} };
List<Factory> factories = new List<Factory>() { new Factory() { Name = "Ferrari", Website = "www.ferrari.it" },
new Factory() { Name = "Jaguar", Website = "www.jaguar.co.uk" },
new Factory() { Name = "BMW", Website = "www.bmw.de"} };
foreach (Car car in cars.Where(c => !factories.Any(f => f.Name == c.Name))) {
lblDebug.Text += car.Name;
}
List<Person> persons1 = new List<Person>
{
new Person {Id = 1, Name = "Person 1"},
new Person {Id = 2, Name = "Person 2"},
new Person {Id = 3, Name = "Person 3"},
new Person {Id = 4, Name = "Person 4"}
};
List<Person> persons2 = new List<Person>
{
new Person {Id = 1, Name = "Person 1"},
new Person {Id = 2, Name = "Person 2"},
new Person {Id = 3, Name = "Person 3"},
new Person {Id = 4, Name = "Person 4"},
new Person {Id = 5, Name = "Person 5"},
new Person {Id = 6, Name = "Person 6"},
new Person {Id = 7, Name = "Person 7"}
};
var output = (from ps1 in persons1
from ps2 in persons2
where ps1.Id == ps2.Id
select ps2.Name).ToList();
人のクラス
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
拡張方法として
public static IEnumerable<TSource> AreNotEqual<TSource, TKey, TTarget>(this IEnumerable<TSource> source, Func<TSource, TKey> sourceKeySelector, IEnumerable<TTarget> target, Func<TTarget, TKey> targetKeySelector)
{
var targetValues = new HashSet<TKey>(target.Select(targetKeySelector));
return source.Where(sourceValue => targetValues.Contains(sourceKeySelector(sourceValue)) == false);
}
例えば。
public class Customer
{
public int CustomerId { get; set; }
}
public class OtherCustomer
{
public int Id { get; set; }
}
var customers = new List<Customer>()
{
new Customer() { CustomerId = 1 },
new Customer() { CustomerId = 2 }
};
var others = new List<OtherCustomer>()
{
new OtherCustomer() { Id = 2 },
new OtherCustomer() { Id = 3 }
};
var result = customers.AreNotEqual(customer => customer.CustomerId, others, other => other.Id).ToList();
Debug.Assert(result.Count == 1);
Debug.Assert(result[0].CustomerId == 1);