【问题标题】:Linq List Any can't handle Value command of generic List<List<T>>Linq List Any 无法处理通用 List<List<T>> 的 Value 命令
【发布时间】:2016-05-11 20:38:50
【问题描述】:

我收到此错误

'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);

应该返回 1,2,3 要么 2,3,4

可能是 1,2,3

注意:return null; 是因为我不知道 x 会返回什么,所以我需要它作为一个列表。

【问题讨论】:

  • 删除.Value。您将TT 进行比较。你没有限制,我不知道你对Value 的期望是什么
  • 是的,删除 .Value 后,`'==' 不能应用于 'T' 和 'T' 类型的操作数`
  • Value 不是 T 的成员。如果您对类型有所了解,您应该使用 public static List&lt;T&gt; FindCommon&lt;T&gt;(List&lt;List&lt;T&gt;&gt; lists) where T : Foo
  • 尝试使用Equals而不是==
  • where lists.All(l =&gt; l.Any(o =&gt; o.Value == option.Value)) 有点奇怪。因为 option 是列表的成员,所以 o 也是。因此,列表的所有成员必须至少有一个元素的光标等于该值。

标签: c# linq list generics any


【解决方案1】:

要编译您的代码,请删除 .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();
}

【讨论】:

  • 返回 0 计数列表
  • 因为您的列表没有任何共同之处。最后一个列表包含所有 5,前 4 个列表没有 5。
  • 哦,我想在所有列表中找到哪个列表在所有其他列表中最常见的主要列表,我列出的示例有 2 个主要列表,我想它应该选择第一个我不知道。
  • 那么你想在主列表中找到重复次数最多的列表吗?如果您有一个包含 {1,2,3} 的列表和另一个包含 {3,2,1} 的列表,它们是否被视为相等?
  • @SSpoke,是的。但是当两个对象给出相同的哈希码时,Equals 将被调用以确定相等性。因此,更好的哈希码计算将为您提供更好的性能。但正确性已经得到保证。
【解决方案2】:

这是我自己解决问题的方法。

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())];
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-27
    • 2019-05-20
    • 1970-01-01
    • 2018-01-15
    • 2018-02-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多