我有一个从外部应用程序返回的人员列表,我在本地应用程序中创建了一个排除列表,让我可以选择从列表中手动删除人员。
我有一个我创建的复合键,两者都很常见,我想找到一种有效的方法,可以使用我的列表从列表中删除人员
例如
class Person
{
prop string compositeKey { get; set; }
}
class Exclusions
{
prop string compositeKey { get; set; }
}
List<Person> people = GetFromDB;
List<Exclusions> exclusions = GetFromOtherDB;
List<Person> filteredResults = People - exclustions using the composite key as a comparer
我认为LINQ是这样做的理想方式,但在尝试连接,扩展方法,使用产量等之后我还是遇到了麻烦。
如果这是SQL,我会使用not in (?,?,?)
查询。
答案 0 :(得分:30)
查看您使用的Except方法:
var resultingList =
listOfOriginalItems.Except(listOfItemsToLeaveOut, equalityComparer)
您将要使用我链接的重载,它允许您指定自定义IEqualityComparer。这样,您可以根据组合键指定项目的匹配方式。 (但是,如果您已经重写了Equals,则不应该使用IEqualityComparer。)
编辑:由于看起来您正在使用两种不同类型的类,因此这是另一种可能更简单的方法。假设名为List<Person>
的{{1}}和名为persons
的{{1}}:
List<Exclusion>
换句话说:只从键中选择排除项,然后从人员中选择不具有任何这些键的所有Person对象。
答案 1 :(得分:4)
我只想在List类上使用FindAll方法。即:
List<Person> filteredResults =
people.FindAll(p => return !exclusions.Contains(p));
不确定语法是否与您的对象完全匹配,但我认为您可以看到我的目标。
答案 2 :(得分:2)
您可以使用“除外”扩展方法(请参阅http://msdn.microsoft.com/en-us/library/bb337804.aspx)
在您的代码中
var difference = people.Except(exclusions);
答案 3 :(得分:2)
非常感谢这个家伙。
我设法将其归结为一行:
var results = from p in People
where !(from e in exclusions
select e.CompositeKey).Contains(p.CompositeKey)
select p;
再次感谢大家。
答案 4 :(得分:1)
我无法弄清楚如何在纯MS LINQ中执行此操作,因此我编写了自己的扩展方法来执行此操作:
public static bool In<T>(this T objToCheck, params T[] values)
{
if (values == null || values.Length == 0)
{
return false; //early out
}
else
{
foreach (T t in values)
{
if (t.Equals(objToCheck))
return true; //RETURN found!
}
return false; //nothing found
}
}
答案 5 :(得分:0)
我会做这样的事情,但我打赌有一种更简单的方法。我认为来自linqtosql的sql会使用一个选择来自不存在的人(从您的排除列表中选择)
static class Program
{
public class Person
{
public string Key { get; set; }
public Person(string key)
{
Key = key;
}
}
public class NotPerson
{
public string Key { get; set; }
public NotPerson(string key)
{
Key = key;
}
}
static void Main()
{
List<Person> persons = new List<Person>()
{
new Person ("1"),
new Person ("2"),
new Person ("3"),
new Person ("4")
};
List<NotPerson> notpersons = new List<NotPerson>()
{
new NotPerson ("3"),
new NotPerson ("4")
};
var filteredResults = from n in persons
where !notpersons.Any(y => n.Key == y.Key)
select n;
foreach (var item in filteredResults)
{
Console.WriteLine(item.Key);
}
}
}
答案 6 :(得分:0)
下面的LINQ将为左外连接生成SQL,然后在排除列表中获取所有未找到匹配项的结果。
List<Person> filteredResults =from p in people
join e in exclusions on p.compositeKey equals e.compositeKey into temp
from t in temp.DefaultIfEmpty()
where t.compositeKey == null
select p
让我知道它是否有效!
答案 7 :(得分:0)
var thisList = new List<string>{ "a", "b", "c" };
var otherList = new List<string> {"a", "b"};
var theOnesThatDontMatch = thisList
.Where(item=> otherList.All(otherItem=> item != otherItem))
.ToList();
var theOnesThatDoMatch = thisList
.Where(item=> otherList.Any(otherItem=> item == otherItem))
.ToList();
Console.WriteLine("don't match: {0}", string.Join(",", theOnesThatDontMatch));
Console.WriteLine("do match: {0}", string.Join(",", theOnesThatDoMatch));
//Output:
//don't match: c
//do match: a,b
相应地调整列表类型和lambda,您可以过滤掉任何内容。
答案 8 :(得分:-1)
var result = Data.Where(x =>
{
bool condition = true;
double accord = (double)x[Table.Columns.IndexOf(FiltercomboBox.Text)];
return condition && accord >= double.Parse(FilterLowertextBox.Text) && accord <= double.Parse(FilterUppertextBox.Text);
});