Linq List Any 无法处理通用 List<List<T>> 的值命令
Linq List Any can't handle Value command of generic List<List<T>>
我收到这个错误
'T' does not contain a definition for 'Value' and no extension method 'Value' accepting a first argument of type 'T' could be found (are you missing a using directive or an assembly reference?)
尝试运行此代码
public static List<T> FindCommon<T>(List<List<T>> lists)
{
var x = from list in lists
from option in list
where lists.All(l => l.Any(o => o.Value == option.Value))
orderby option.Value
select option;
return null;
}
测试代码
List<List<uint>> Patterns = new List<List<uint>>();
Patterns.Add(new List<uint>() { 1, 2, 3 });
Patterns.Add(new List<uint>() { 2, 3, 4 });
Patterns.Add(new List<uint>() { 2, 3, 4 });
Patterns.Add(new List<uint>() { 1, 2, 3 });
Patterns.Add(new List<uint>() { 5, 5, 5 });
List<uint> finalOffsets = FindCommon(Patterns);
应该return
1,2,3
要么
2,3,4
可能是 1,2,3
注意: return null;
是因为我不知道 x 会做什么 return 我需要它是一个列表。
要编译代码,删除 .Value
并使用 Equals
方法而不是 ==
。但是,这仍然无法满足您的需求(据我了解您的目标)。
根据我对你的理解,你想找到主列表中重复次数最多的列表。方法如下:
首先,定义一个知道如何比较列表的比较器:
public class ListEqualityComparer<T> : IEqualityComparer<List<T>>
{
public bool Equals(List<T> x, List<T> y)
{
return x.SequenceEqual(y);
}
public int GetHashCode(List<T> obj)
{
//This works. But you might want to have a
//better way for calculating the hash code
return obj.Sum(x => x.GetHashCode());
}
}
然后你可以这样使用它:
public static List<T> FindCommon<T>(List<List<T>> lists)
{
return lists.GroupBy(x => x, new ListEqualityComparer<T>())
.OrderByDescending(g => g.Count())
.Select(g => g.Key)
.FirstOrDefault();
}
以下是我自己解决问题的方法。
public static List<T> FindCommon<T>(List<List<T>> lists)
{
List<uint> Counts = new List<uint>();
List<List<T>> Matches = new List<List<T>>();
bool Found = false;
foreach (List<T> list in lists)
{
Found = false;
for (int i = 0; i < Counts.Count; i++)
{
if (Matches[i].Count == list.Count)
{
for (int j = 0; j < list.Count; j++)
{
//they not equals
if ((dynamic)Matches[i][j] != (dynamic)list[j])
goto next_loop;
//fully equal, increase count for repeated match found.
if (j == list.Count - 1)
{
Counts[i]++;
Found = true;
break;
}
}
}
next_loop:
if (Found) break;
continue;
}
if (!Found)
{
Counts.Add(1);
Matches.Add(list);
}
}
return Matches[Counts.IndexOf(Counts.Max())];
}
我收到这个错误
'T' does not contain a definition for 'Value' and no extension method 'Value' accepting a first argument of type 'T' could be found (are you missing a using directive or an assembly reference?)
尝试运行此代码
public static List<T> FindCommon<T>(List<List<T>> lists)
{
var x = from list in lists
from option in list
where lists.All(l => l.Any(o => o.Value == option.Value))
orderby option.Value
select option;
return null;
}
测试代码
List<List<uint>> Patterns = new List<List<uint>>();
Patterns.Add(new List<uint>() { 1, 2, 3 });
Patterns.Add(new List<uint>() { 2, 3, 4 });
Patterns.Add(new List<uint>() { 2, 3, 4 });
Patterns.Add(new List<uint>() { 1, 2, 3 });
Patterns.Add(new List<uint>() { 5, 5, 5 });
List<uint> finalOffsets = FindCommon(Patterns);
应该return 1,2,3 要么 2,3,4
可能是 1,2,3
注意: return null;
是因为我不知道 x 会做什么 return 我需要它是一个列表。
要编译代码,删除 .Value
并使用 Equals
方法而不是 ==
。但是,这仍然无法满足您的需求(据我了解您的目标)。
根据我对你的理解,你想找到主列表中重复次数最多的列表。方法如下:
首先,定义一个知道如何比较列表的比较器:
public class ListEqualityComparer<T> : IEqualityComparer<List<T>>
{
public bool Equals(List<T> x, List<T> y)
{
return x.SequenceEqual(y);
}
public int GetHashCode(List<T> obj)
{
//This works. But you might want to have a
//better way for calculating the hash code
return obj.Sum(x => x.GetHashCode());
}
}
然后你可以这样使用它:
public static List<T> FindCommon<T>(List<List<T>> lists)
{
return lists.GroupBy(x => x, new ListEqualityComparer<T>())
.OrderByDescending(g => g.Count())
.Select(g => g.Key)
.FirstOrDefault();
}
以下是我自己解决问题的方法。
public static List<T> FindCommon<T>(List<List<T>> lists)
{
List<uint> Counts = new List<uint>();
List<List<T>> Matches = new List<List<T>>();
bool Found = false;
foreach (List<T> list in lists)
{
Found = false;
for (int i = 0; i < Counts.Count; i++)
{
if (Matches[i].Count == list.Count)
{
for (int j = 0; j < list.Count; j++)
{
//they not equals
if ((dynamic)Matches[i][j] != (dynamic)list[j])
goto next_loop;
//fully equal, increase count for repeated match found.
if (j == list.Count - 1)
{
Counts[i]++;
Found = true;
break;
}
}
}
next_loop:
if (Found) break;
continue;
}
if (!Found)
{
Counts.Add(1);
Matches.Add(list);
}
}
return Matches[Counts.IndexOf(Counts.Max())];
}