2015-06-26 2 views
0

У меня есть два списка. Мои списки выглядеть следующим образом:Использование внешнего соединения с LINQ

AvailableFlavors

ID Name 
-- ---- 
1 Vanilla 
2 Chocolate 
3 Strawberry 
4 Rocky Road 
5 Cookies and Cream 

FavoriteFlavors

ID Name 
-- ---- 
1 Vanilla 
3 Strawberry 

Как получить список AvailableFlavors, которые не в списке FavoriteFlavors с помощью LINQ? В настоящее время у меня есть:

List<Flavor> AvailableFlavors = GetAvailableFlavors(); 
List<Flavor> FavoriteFlavors = GetFavoriteFlavors(); 

AvailableFlavors = from availableFlavor in AvailableFlavors 
        // what goes here? 
        select availableFlavor; 

ответ

0

Простой LINQ .Except вызов будет делать трюк:

List<Flavor> AvailableFlavors = GetAvailableFlavors(); 
List<Flavor> FavoriteFlavors = GetFavoriteFlavors(); 
var availableButNotFavoriteFlavors = AvailableFloavors.Except(FavoriteFlaovors); 

Результат является IEnumerable<Flavor>, так что вам, возможно, потребуется преобразовать обратно в список ,

Редактировать: Реальный вопрос, я думаю, это как написать пользовательский IEqualityComparer, который мы используем в методе `.Except '. На этой странице документации .Except есть хороший пример написания простого сравнения.

Если вы не можете быть обеспокоены, что делать, альтернативный вариант просто использовать .Where и вручную сравнить свойства:

+0

О, мужчина! Это так круто. Я понятия не имел, что опция «Исключить» даже существовала. Замечательно! –

-1
AvailableFlavors.Where(af => !FavoriteFlavors.Any(ff => af.Name == ff.Name)); 
+0

Это неправильно, потому что вы не можете предположить, OP имеет переопределены '' Equals' для Flavor' – rexcfnghk

+0

Это правда, но не зная, что содержит объект Flavor, сложно дать точный код. Почему бы не работать, если он реализует ==? Это следует рассматривать как псевдокод, учитывая приведенные выше детали. Зачем ты это сделал? – peinearydevelopment

+0

В основном вы ответили на свой вопрос. Я отклонил ваш ответ, потому что вы ** предполагаете ** реализацию «Flavor» без каких-либо объяснений в вашем ответе – rexcfnghk

0

С пользовательского класса Flavor Я перегрузили Equals() и ToString() и сделал следующие:

using System; 
using System.Collections.Generic; 
using System.Linq; 

public class Program 
{ 
    public static void Main() 
    { 
     List<Flavor> availableFlavors = new List<Flavor>() { 
      new Flavor() { ID = 1, Name = "Vanilla" }, 
      new Flavor() { ID = 2, Name = "Chocolate" }, 
      new Flavor() { ID = 3, Name = "Strawberry" }, 
      new Flavor() { ID = 4, Name = "Rocky Road" }, 
      new Flavor() { ID = 5, Name = "Cookies and Cream"} 
     }; 

     List<Flavor> favoriteFlavors = new List<Flavor>() { 
      new Flavor() { ID = 1, Name = "Vanilla" }, 
      new Flavor() { ID = 3, Name = "Strawberry" }, 
     }; 

     availableFlavors.Where(f => !favoriteFlavors.Contains(f)) 
      .ToList() 
      .ForEach(f => Console.WriteLine(f)); 
    } 
} 

public class Flavor 
{ 
    public int ID { get; set; } 
    public string Name { get; set; } 

    public override bool Equals(object obj) 
    { 
     Flavor objToCheck = obj as Flavor; 
     if (objToCheck != null) 
     { 
      if (objToCheck.ID == ID && 
       objToCheck.Name == Name) 
      { 
       return true; 
      } 
      return false; 
     } 
     return false; 
    } 

    public override string ToString() 
    { 
     return String.Format("ID: {0} Name: {1}", ID, Name); 
    } 
} 

Результаты:

ID: 2 Name: Chocolate 
ID: 4 Name: Rocky Road 
ID: 5 Name: Cookies and Cream 

Demo

+0

Это технически корректно, но нет необходимости изменять структуру класса, чтобы выполнить простую фильтрацию. – rexcfnghk

0
// Select Name from favorite flavors 
var favoriteFlavorNames = from favoriteFlavor in GetFavoriteFlavors() 
          select favoriteFlavor.Name; 

// Find available flavors not in favorite flavors 
var filteredAvailbleFlavors = from availableFlavor in GetAvailableFlavors() 
           where !favoriteFlavorNames.Contains(availableFlavor.Name) 
           select availableFlavor; 

Или вы можете объединить два в:

var filteredAvailbleFlavors = from availableFlavor in GetAvailableFlavors() 
           let favoriteFlavorNames = 
            (from favoriteFlavor in GetFavoriteFlavors() 
            select favoriteFlavor.Name) 
           where !favoriteFlavorNames.Contains(availableFlavor.Name) 
           select availableFlavor;