web-dev-qa-db-fra.com

compare deux listes et retourne les éléments ne correspondant pas à l'aide de linq

j'ai une liste de deux

List<Sent> SentList;
List<Messages> MsgList;

les deux ont la même propriété appelée MsgID;

MsgList            SentList  

MsgID Content      MsgID Content Stauts
1       aaa        1       aaa     0
2       bbb        3       ccc     0
3       ccc        
4       ddd
5       eee

je veux comparer le MsgID dans Msglist avec la liste d'envoi et avoir besoin d'éléments qui ne sont pas dans la liste d'envoi en utilisant linq

Result 

MsgID Content
2       bbb
4       ddd
5       eee
20
Spen D

Vous pourriez faire quelque chose comme:

HashSet<int> sentIDs = new HashSet<int>(SentList.Select(s => s.MsgID));

var results = MsgList.Where(m => !sentIDs.Contains(m.MsgID));

Ceci retournera tous les messages dans MsgList qui n'ont pas d'identifiant correspondant dans SentList.

28
Reed Copsey

L'approche naïve:

MsgList.Where(x => !SentList.Any(y => y.MsgID == x.MsgID))

Sachez que cela prendra jusqu'à m*n opérations car il compare chaque MsgID dans SentList à chacune dans MsgList ("jusqu'à" parce qu'il court-circuitera quand il fait arrive à correspondre).

14
lc.

Eh bien, vous avez déjà de bonnes réponses, mais ce sont surtout Lambda. Une approche plus LINQ serait comme

var NotSentMessages =
                from msg in MsgList
                where !SentList.Any(x => x.MsgID == msg.MsgID)
                select msg;
11
Andre Calil

Vous pouvez faire quelque chose comme

var notSent = MsgSent.Except(MsgList, MsgIdEqualityComparer);

Vous devrez fournir un comparateur d’égalité personnalisé, comme indiqué sur MSDN.

http://msdn.Microsoft.com/en-us/library/bb336390.aspx

Ayez simplement cette égalité de base de comparateur d'égalité uniquement sur la propriété MsgID de chaque type respectif. Dans la mesure où le comparateur d'égalité compare deux instances du même type, vous devez définir un type d'interface ou de base commune que Sent et Messages implémentent et qui possède une propriété MsgID.

8
Eric J.

Vous pouvez faire comme ça, c'est le processus le plus rapide

Var result = MsgList.Except(MsgList.Where(o => SentList.Select(s => s.MsgID).ToList().Contains(o.MsgID))).ToList();

Cela vous donnera la sortie attendue.

4
Tushar patel

Essayer,

  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>();

J'espère que ça devrait aider.

2
Jignesh Thakker
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;
}
0
Tys

Comme méthode d'extension

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);
}

par exemple.

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);
0
Matt Searles