在LINQ中高效的列表自比较
本文关键字:列表 比较 高效 LINQ | 更新日期: 2023-09-27 18:14:45
这可能与这个问题非常相似,但我想知道c#和LINQ中最有效的方法来比较同一列表中的元素列表。
例如,在伪代码中我想这样做:
foreach(i in list)
foreach(j in list.Except(i))
Compare(j,i)
我知道Except接受一个可枚举对象而不是单个对象,这可能不是最好的主意,但它应该说明我的意图。
任何想法?
更新:
我想这个问题有点模糊。目标是在列表上迭代两次(使用LINQ),同时跳过对(i, i)
;无论Compare(i,j)
实际做什么都与我的问题无关。
有两种情况,一种是(i,j) == (j,i)
和(i,j) != (j,i)
。对于前者,George Duckett的跳跃式解决方案可以解决问题,但对于后者呢?这就是我最初使用Except的地方,这样(i,j)
和(j,i)
都将被求值。
那么澄清一下,除了list.Except(Enumerable.Repeat(i,1))
之外,有没有更好的方法来跳过列表中的元素呢?
这将给你所有的配对,假设配对的顺序无关(Compare(i, j) == Compare(j, i)
):
var test = from i in list
from j in list.SkipWhile(j => j != i)
where i != j // Remove the self-comparison if you want to
select Compare(i, j);
我不知道你是否对LINQ有需求,但我很可能会这样写这段代码,这样当我从现在起3周后回顾代码时,我一眼就知道是怎么回事。
for(var i = 0; i < list.Count; ++i)
{
var item = list[i];
for(var j = i+1; j < list.Count; ++j)
{
Compare(item, list[j]);
}
}
如果你还想使用LINQ,你可以这样重写:
for(var i = 0; i < list.Count; ++i)
{
var item = list[i];
foreach(var j in list.Skip(i+1))
{
Compare(item, j);
}
}
您的需求需要更多的说明,但这可以帮助您:
List<int> list = new List<int>() { 1, 2, 3, 4 };
var result = list.Aggregate((p, q) => p.CompareTo(q) > 0 ? p : q);//Return 4
你的问题有点模糊,你想用比较的结果做什么,但这里有一个想法:
public static IEnumerable<TResult> Compare<T, TResult>(this IEnumerable<T> source, Func<T, T, TResult> func)
{
int i = 0;
foreach (T item1 in source)
{
foreach (T item2 in source.Skip(i))
yield return func(item1, item2);
i++;
}
}
然后你可以对比较的结果做任何你想做的事情。例如,使用这些List
对象:
List<string> list = new List<string> { "test", "hello", "foo", "bar" };
你可以这样做:
var compared = list.Compare((item1, item2) => item1.Equals(item2));
//compared will be IEnumerable<bool> in this case
或:
var compared = list.Compare((item1, item2) => new { item1, item2 });
//to get an enumerator of all the different comparisons of the 2 lists