我有一个包含3个项目的列表,其中两个是type_1,另一个是type_2。我想返回第二个列表,其中包含该类型的类型和编号。单步执行foreach循环中设置的断点时,IF语句永远不会成立。我假设我尝试使用Contains()方法有问题。
输出应该是这样的:
type_1 2
type_2 1
相反,它评估为:
type_1 1
type_1 1
type_2 1
我对Contains()的使用不正确吗?
public List<item_count> QueryGraphListingsNewAccountReport()
List<item> result = new List<items>();
var type_item1 = new item { account_type = "Type_1" };
var type_item2 = new item { account_type = "Type_1" };
var type_item3 = new item { account_type = "Type_2" };
result.Add(type_item1);
result.Add(type_item2);
result.Add(type_item3);
//Create a empty list that will hold the account_type AND a count of how many of that type exists:
List<item_count> result_count = new List<item_count>();
foreach (var item in result)
{
if (result_count.Contains(new item_count { account_type = item.account_type, count = 1 } ) == true)
{
var result_item = result_count.Find(x => x.account_type == item.account_type);
result_item.count += 1;
result_count.Add(result_item);
}
else
{
var result_item = new item_count { account_type = item.account_type, count = 1 };
result_count.Add(result_item);
}
}
return result_count;
}
public class item
{
public string account_type { get; set; }
}
public class item_count
{
public int count {get; set;}
public string account_type { get; set; }
}
答案 0 :(得分:2)
你可以这样做:
myList.GroupBy(x=>x.type).Select(x=>new {x.Key, x.Count()});
如果你想使用for循环,最好使用linq Count
函数来实现这一点,如果你想使用Contains,你应该像你使用的那样实现相同的运算符。
答案 1 :(得分:2)
我认为您的问题是您根本不想使用包含。您正在contains语句中创建一个新对象,显然,它已经没有包含在您的列表中,因为您刚刚创建它。比较是比较参考,而不是价值。
为什么不使用你在下一行中执行的find语句呢?如果它返回null,那么您知道没有已经具有该类型的项目。
所以你可以这样做:
var result_item = result_count.Find(x => x.account_type == item.account_type);
if (result_item != null)
{
result_item.count++;
// note here you don't need to add it back to the list!
}
else
{
// create your new result_item here and add it to your list.
}
注意:查找为o(n),因此如果您拥有非常多的类型,这可能无法很好地扩展。在这种情况下,你可能会对Saeed的分组建议感觉更好。