[英]Using an outer join with LINQ
I have two lists. 我有两个清单。 My lists look like this: 我的列表如下所示:
AvailableFlavors 可用香料
ID Name
-- ----
1 Vanilla
2 Chocolate
3 Strawberry
4 Rocky Road
5 Cookies and Cream
FavoriteFlavors 最喜欢的
ID Name
-- ----
1 Vanilla
3 Strawberry
How do I get a list of AvailableFlavors
that are NOT in the list of FavoriteFlavors
using LINQ? 如何获得使用LINQ不在FavoriteFlavors
列表中的AvailableFlavors
列表? Currently I have: 目前我有:
List<Flavor> AvailableFlavors = GetAvailableFlavors();
List<Flavor> FavoriteFlavors = GetFavoriteFlavors();
AvailableFlavors = from availableFlavor in AvailableFlavors
// what goes here?
select availableFlavor;
With your custom class Flavor
I overrode the Equals()
and ToString()
and did the following: 使用您的自定义类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);
}
}
Results: 结果:
ID: 2 Name: Chocolate
ID: 4 Name: Rocky Road
ID: 5 Name: Cookies and Cream
// 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;
Or you can combine the two into: 或者,您可以将两者合并为:
var filteredAvailbleFlavors = from availableFlavor in GetAvailableFlavors()
let favoriteFlavorNames =
(from favoriteFlavor in GetFavoriteFlavors()
select favoriteFlavor.Name)
where !favoriteFlavorNames.Contains(availableFlavor.Name)
select availableFlavor;
Simple LINQ .Except
call will do the trick: 简单的LINQ .Except
调用可以解决问题:
List<Flavor> AvailableFlavors = GetAvailableFlavors();
List<Flavor> FavoriteFlavors = GetFavoriteFlavors();
var availableButNotFavoriteFlavors = AvailableFloavors.Except(FavoriteFlaovors);
The result is IEnumerable<Flavor>
, so you might need convert back to List. 结果是IEnumerable<Flavor>
,因此您可能需要转换回List。
Edit : The real question I guess is how to write a custom IEqualityComparer
which we use in `.Except' method. 编辑 :我猜的真正问题是如何编写自定义IEqualityComparer
,我们在`.Except'方法中使用。 This .Except documentation page has a good example of write a simple comparer. 该.Except文档页面有一个编写简单比较器的好例子。
If you can't be bothered doing that, an alternative option is just use .Where
and manually compare properties: 如果您不愿意这样做,则可以使用.Where
并手动比较属性:
var availableButNotFavoriteFlavors =
AvailableFloavors
.Where(af => !FavoriteFlavors.Any(ff => af.Id == ff.ID && af.Name == ff.Name);
AvailableFlavors.Where(af => !FavoriteFlavors.Any(ff => af.Name == ff.Name));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.