问题:如何简化下面的代码,因为我的目标是在事物类中有30个不同的属性。
代码在'thing'属性中寻找唯一性。
public class thing
{
public string Name { get; set; }
public string Colour { get; set; }
public string Position { get; set; }
public string Height { get; set; }
}
public List<thing> SeeIfAnyInListHaveAUniqueSingleColumn(List<thing> listOfThings)
{
// try colour
IEnumerable<IGrouping<string, thing>> thingQuery2 = from t in listOfThings
group t by t.Colour;
List<thing> listOfThingsFound = new List<thing>();
foreach (var thingGroup in thingQuery2)
{
if (thingGroup.Count() == 1)
{
foreach (thing thing in thingGroup) // there is only going to be 1
listOfThingsFound.Add(thing);
}
}
// try position
IEnumerable<IGrouping<string, thing>> thingQuery3 = from t in listOfThings
group t by t.Position;
foreach (var thingGroup in thingQuery3)
{
if (thingGroup.Count() == 1)
{
foreach (thing thing in thingGroup) // there is only going to be 1
listOfThingsFound.Add(thing);
}
}
return listOfThingsFound;
}
http://www.programgood.net/2010/11/06/FindingUniquenessInData.aspx
上的可下载代码答案 0 :(得分:1)
我认为如果你抽象出FindUnique
操作,你可以更轻松地编写测试:
static IEnumerable<T> FindDistinct<T, TKey>(this IEnumerable<T> source,
Func<T, TKey> keySelector)
{
return from item in source
group item by keySelector(item) into grp
where grp.Count() == 1
from single in grp
select single;
}
然后你可以写:
var thingsWithUniqueName = listOfThings.FindDistinct(t => t.Name);
var thingsWithUniquePosition = listOfThings.FindDistinct(t => t.Position);
var thingsWithUniqueHeight = listOfThings.FindDistinct(t => t.Height);
答案 1 :(得分:0)
您想编写如下代码:
foreach var property in Thing.Properties
{
IEnumerable<IGrouping<string, thing>> thingQuery2 = from t in listOfThings
group t by t.property;
List<thing> listOfThingsFound = new List<thing>();
foreach (var thingGroup in thingQuery2)
{
if (thingGroup.Count() == 1)
{
foreach (thing thing in thingGroup) // there is only going to be 1
listOfThingsFound.Add(thing);
}
}
...
}
你只能通过反思做到这一点,这是你应该远离的东西。我唯一能想到的是将属性存储在某种集合中,比如字典和迭代 。
答案 2 :(得分:0)
我刚注意到Gabe已经提供了我即将发布的相同答案。我以为我会发布这个只是为了强调这个答案是LINQ的一个很好的用途。 请接受Gabe的回答,而不是这个回答。做得好Gabe!
public static IEnumerable<T> WhereUniqueByKey<T, P>(
this IEnumerable<T> @this, Func<T, P> keySelector)
{
return @this
.GroupBy(keySelector)
.Where(gt => gt.Count() == 1)
.SelectMany(gt => gt, (_, t) => t);
}
根据Gabe的回答,我的函数是一个扩展方法,需要在静态类中定义。我们的答案之间唯一真正的区别是Gabe使用了LINQ查询语法,我使用了直接的LINQ方法调用。结果是相同的,使用情况也是如此:
var thingsWithUniqueName = listOfThings.WhereUniqueByKey(t => t.Name);
var thingsWithUniquePosition = listOfThings.WhereUniqueByKey(t => t.Position);
var thingsWithUniqueHeight = listOfThings.WhereUniqueByKey(t => t.Height);