我想在一个集合中找到与另一个集合不匹配的所有项目.但是,这些集合的类型不同; 我想编写一个lambda表达式来指定相等性.
一个LINQPad我正在尝试做的例子:
void Main()
{
var employees = new[]
{
new Employee { Id = 20, Name = "Bob" },
new Employee { Id = 10, Name = "Bill" },
new Employee { Id = 30, Name = "Frank" }
};
var managers = new[]
{
new Manager { EmployeeId = 20 },
new Manager { EmployeeId = 30 }
};
var nonManagers =
from employee in employees
where !(managers.Any(x => x.EmployeeId == employee.Id))
select employee;
nonManagers.Dump(); …Run Code Online (Sandbox Code Playgroud) 我有两个排序列表如下:
var list1 = new List<int>() { 1, 1, 1, 2, 3 };
var list2 = new List<int>() { 1, 1, 2, 2, 4 };
Run Code Online (Sandbox Code Playgroud)
我希望输出为: {1, 1, 2}
如何在C#中做到这一点?有没有办法使用Linq?
对于实现大量的IEqualityComparers有些懒惰,并且考虑到我无法轻松编辑被比较对象的类实现,我使用了以下内容,意味着与Distinct()和Except()扩展方法一起使用.:
public class GenericEqualityComparer<T> : IEqualityComparer<T>
{
Func<T, T, bool> compareFunction;
Func<T, int> hashFunction;
public GenericEqualityComparer(Func<T, T, bool> compareFunction, Func<T, int> hashFunction)
{
this.compareFunction = compareFunction;
this.hashFunction = hashFunction;
}
public bool Equals(T x, T y)
{
return compareFunction(x, y);
}
public int GetHashCode(T obj)
{
return hashFunction(obj);
}
}
Run Code Online (Sandbox Code Playgroud)
看起来不错,但每次真的需要一个哈希函数?我知道哈希码用于将对象放入存储桶中.不同的桶,对象不相等,并且不调用相等.
如果GetHashCode返回相同的值,则调用equals.(来自:为什么在重写Equals方法时重写GetHashCode很重要?)
那么可能出现什么问题,例如(我听到很多程序员惊恐地尖叫),GetHashCode返回一个常量,强制调用Equal?
我有一个我想要交叉的列表列表:
List<List<int>> input = new List<List<int>>();
input.Add(new List<int>() { 1, 2, 4, 5, 8 });
input.Add(new List<int>() { 3, 4, 5 });
input.Add(new List<int>() { 1, 4, 5, 6 });
Run Code Online (Sandbox Code Playgroud)
输出应该是:
{ 4, 5 }
Run Code Online (Sandbox Code Playgroud)
如何以简洁的方式实现这一目标?
在我学习计算机科学的过程中,我遇到了一些像Prolog这样的函数式语言,但是现在我在过去的10年里只做过像C#,Ruby JavaScript和Java这样的命令式的东西.目前我正在为网上商店创建一个全文搜索引擎,我已经走到了"必要的方式".但是,遇到像Caskjure的Haskell这样的函数式语言时,很明显功能范式非常合适,并且命令式方法不适合这项工作.
所以我们有一个大约1000万条记录的全文索引.每个记录基本上包含一个单词出现,以及它所来自的记录中的id和text位置.
当用户输入搜索字符串时,它将被解析为表达式树.例如,搜索字符串"transformer 100 W"会产生类似的结果
AND('transformer%', OR(NEAR('100', 'W'), NEAR('100', 'watts'), '100W', '0.1kW'))
Run Code Online (Sandbox Code Playgroud)
这里还有一些额外的"情报",但这个问题无关紧要.
然后递归地评估表达式树,并导致一些sql查询,这些查询可以以.NET-DataTables的形式返回多达100,000行.然后将它们读入集合或字典中,并根据谓词应用交叉点和联合,以便找到与整个搜索表达式匹配的所有结果.对于NEAR评估,还比较找到的事件的位置索引.但这一切都是必须完成的,有很多for循环.
此外,还有一个排名功能,可以将找到的单词出现次数加起来.仅作为前缀或模糊匹配(由数据库服务器完成)的单词得分低于精确匹配.
对于每个结果项,我还需要获得匹配的所有单词出现的列表,以便在结果页中突出显示这些单词.
所以大致评估算法是一个像
expression tree, full text index ->
resulting items that match the expressin tree,
each with a ranking sum
and a list of all found word occurrences for this item
Run Code Online (Sandbox Code Playgroud)
我只是在这里给出一个粗略的概述,但我希望你能得到足够的图片.
现在"现实世界"的限制:
由于我需要继续使用.NET,我正在研究Clojure-CLR,F#和Scala for .NET.
我很喜欢Clojure的概念,但是现在我无法评估它是否符合这项工作.阅读F#给了我复杂的感受,因为它似乎想要能够完成所有事情,而我倾向于为给定的任务采用更"纯粹"的数学方法.但也许F#也可以这样做,我还没有意识到这一点.我还没有深入研究过Scala,但它似乎已经很成熟了.
任何见解都会受到欢迎!
我有一个清单.我想过滤表格列表中的所有行,以查找列表中每个数据表中的所有行.
如果可能,比较需要在每行的"ID"列上.
我试图用Linq解决这个问题但是卡住了.这是我到目前为止:
List<DataTable> dataTables = new List<DataTable>();
// fill up the list
List<DataRow> dataRows =
dataTables.SelectMany(dt => dt.Rows.Cast<DataRow>().AsEnumerable()).
Aggregate((r1, r2) => r1.Intersect(r2));
Run Code Online (Sandbox Code Playgroud)
有什么建议?
给定一个列表列表(假设有5个列表,要有一个可以使用的实数),我可以相对轻松地找到所有5个列表共有的项(参见使用IEnumerable.Intersect()的多个列表的交集)以下代码的变体:
var list1 = new List<int>() { 1, 2, 3 };
var list2 = new List<int>() { 2, 3, 4 };
var list3 = new List<int>() { 3, 4, 5 };
var listOfLists = new List<List<int>>() { list1, list2, list3 };
var intersection = listOfLists.Aggregate((previousList, nextList) => previousList.Intersect(nextList).ToList());
Run Code Online (Sandbox Code Playgroud)
现在让我们说intersection最终包含0个项目.很可能有一些对象是4/5列表中常见的.我将如何以最有效的方式找到它们?
我知道我可以运行4个列表的所有组合并保存所有结果,但该方法不能很好地扩展(这最终必须在大约40个列表上完成).
如果4个列表中没有共同的项目,那么将重复搜索以查找3/5列表共有的项目等.在视觉上,这可以通过网格点列表来表示,我们正在搜索最多的点交叠.
有任何想法吗?
编辑:也许最好是查看每个点并跟踪它在每个列表中出现的次数,然后创建出现次数最多的点列表?
我有一份清单清单:
List<Tuple<string, List<SomeObject>>
Run Code Online (Sandbox Code Playgroud)
我想选择SomeObjects上面列表的所有行中存在的所有内容.
有些只会存在于一个或两个列表中,但我希望所有对象都存在于每个列表中,而其他对象则被丢弃.
如果没有一堆c#代码,我无法找到一个优雅的解决方案.有一个很好的方式吗?
我有一个dictionary<int, List<string>>,我希望与每个int的所有列表相交.
我怎么做到这一点?我觉得这应该很容易,但由于某种原因,它没有成功.
谢谢.
从基础课开始:
public class Car
{
public string Name {get;set;}
}
Run Code Online (Sandbox Code Playgroud)
然后我可以创建这些车的列表
List<Car> cars = new List<Car>();
Run Code Online (Sandbox Code Playgroud)
新步骤是拥有此列表的列表,如下所示:
List<List<Car>> allListsOfCars = new List<List<Car>>();
Run Code Online (Sandbox Code Playgroud)
在填充allListsOfCars之后,我想将它传递给一个函数,该函数将返回每个List列表中存在的汽车.
我知道这听起来令人困惑,所以我会尝试解释一下.
如果我有ListA,ListB,ListC所有类型List - 现在将它们组合成1个保持列表(列表列表),那么如何才能找回每个列表中存在的所有车辆?例如,如果汽车只存在于ListA中,那么我不感兴趣,它需要存在于ListA和ListB AND ListC中,然后我希望它添加到结果集并返回.
提前致谢.