[英]how to check if List<T> element contains an item with a Particular Property Value
[英]Check if List<T> element contains an item with a Particular Property Value
public class Item
{
public List<int> val { get; set; }
public double support { get; set; }
}
我聲明變量:
List<Item> t = new List<Item>();
t.Add(new Item(){val = new List<int>(){1,2,3};support=.1);
var b = new Item();
b.val = t[0].val;
b.support=t[0].support;
t.Contain(b) // return false???
我正在嘗試使用 linq
t.Any(a=>a.val==b.val) // I'm get error Expression cannot contain lambda expressions
想到了3種可能性:
你可以實現IEquatable<T>
:
public class Item: IEquatable<Item>
{
public List<int> val { get; set; }
public double support { get; set; }
public bool Equals(Item other)
{
return
this.support == other.support &&
this.val.SequenceEqual(other.val);
}
}
現在t.Contains(b)
將返回 true。
如果您無法修改Item
類,您可以編寫自定義EqualityComparer :
public class ItemEqualityComparer : IEqualityComparer<Item>
{
private ItemEqualityComparer()
{
}
public static IEqualityComparer<Item> Instance
{
get
{
return new ItemEqualityComparer();
}
}
public bool Equals(Item x, Item y)
{
return
x.support == y.support &&
x.val.SequenceEqual(y.val);
}
public int GetHashCode(Item obj)
{
int hash = 27;
hash += (13 * hash) + obj.support.GetHashCode();
foreach (var item in obj.val)
{
hash += (13 * hash) + item.GetHashCode();
}
return hash;
}
}
然后t.Contains(b)
也將返回true
。
或者,如果您更喜歡簡單地做這件事:
List<Item> t = new List<Item>();
t.Add(new Item { val = new List<int>(){1,2,3}, support=.1 });
var b = new Item();
b.val = t[0].val;
b.support = t[0].support;
bool equals = t.All(item => item.support == b.support && item.val.SequenceEqual(b.val));
Console.WriteLine(equals);
你的t.Any(a=>a.val == b.val)
是正確的。
您得到的錯誤來自調試器中的快速觀察或表達式窗口,而不是來自編譯器。 Visual Studio 的表達式計算器不處理 lambda。 但是,它仍然是有效的 c# 代碼,並且會執行您想要的操作。
這是你之前的問題:
t.Add(new Item(){val = new List<int>(){1,2,3};support=.1);
這是各種不同語法位的混合。 它應該是:
t.Add(new Item(){val = new List<int>(){1,2,3}, support=.1});
...雖然最好使用更好的屬性名稱等。然后其余的應該可以工作 - 盡管您需要對Any
的結果做一些事情。 Any
調用本身是有效的。 這是一個簡短但完整的程序,它有效:
using System;
using System.Collections.Generic;
using System.Linq;
public class Item
{
public List<int> Values { get; set; }
public double Support { get; set; }
}
class Test
{
static void Main()
{
List<Item> list = new List<Item>
{
new Item { Values = new List<int>{1, 2, 3},
Support = 0.1 }
};
var check = new Item { Values = list[0].Values,
Support = list[0].Support };
bool found = list.Any(a => a.Values == check.Values);
Console.WriteLine(found);
}
}
請注意,這是在兩個列表之間執行參考比較 - 如果您創建了具有相同值 (1, 2, 3) 的不同列表,則不會找到該列表。 您需要使用a.Values.SequenceEqual(b.Values)
或類似的東西。
您的Item
類應該實現IEquatable
接口:
class Item : IEquatable<Item>{
public List<int> val { get; set; }
public double support { get; set; }
public bool Equals(Item item){
return this.support.Equals(item.support) && this.val.SequenceEqual(item.val);
}
}
那么Contains()
方法應該可以正常工作。
你可以糾正你的
“ t.Contain(b)
”
到
t.Contains(b, new ItemEqualityComparer())
來自System.Linq
其中ItemEqualityComparer
將是您的類,它將實現IEqualityComparer<Item>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.