给出列表中包含数千个对象的列表,如下所示:
var list = new List<PointAddress>();
list.Add(new PointAddress { Line = 1, Number = 100f });
list.Add(new PointAddress { Line = 1, Number = 101f });
list.Add(new PointAddress { Line = 1, Number = 105f });
list.Add(new PointAddress { Line = 1, Number = 106f });
list.Add(new PointAddress { Line = 2, Number = 103f });
list.Add(new PointAddress { Line = 2, Number = 104f });
创建无间隙范围(基于Number属性)的最佳方法是什么,如下所示? 如果差异>数字属性中的1是间隙,数字应该在不同的组中。
第1组
Line = 1,Number = 100f
Line = 1,Number = 101f
第2组
Line = 1,Number = 105f
Line = 1,Number = 106f
第3组
Line = 2,Number = 103f
Line = 2,Number = 104f
基本上如果Gap&gt; 1然后它应该在Line的不同组中。
如果该行不同,则它是不同的组。如果Number是相邻的数字且Line是相同的,那么它必须在示例中所示的同一组中。第1行分为2组 - 第1组和第2组,因为数字不相邻。
答案 0 :(得分:2)
假设您的列表已订购,则以下内容应该有效。
首先,一个简单的通用Linq扩展来对列表进行分区:
public static IEnumerable<List<T>> Partition<T>( this IEnumerable<T> source , Func<T,T,bool> areAdjacent )
{
List<T> list = null ;
T prev = default(T) ;
foreach ( T curr in source )
{
if ( list == null )
{
list = new List<T> {curr} ;
}
else if ( areAdjacent(prev,curr) )
{
list.Add(curr) ;
}
else
{
yield return list ;
list = new List<T> {curr} ;
}
prev = curr ;
}
if ( list != null )
{
yield return list ;
}
}
然后你可以调用它
List<PointAddress> addressList = GetSomeEnormousList() ;
List<List<PointAddress>> ranges = addressList
.Partition( (prev,curr) => curr.Line == prev.Line && curr.Number - prev.Number == 1.0 )
.ToList()
;
你需要的只是一个lambda,它将获取两个PointAddress
项并比较它们以确定是否存在序列中断,如果认为这两个项是相邻的,则返回true
或{{ 1}}如果他们不是。如何确定订单中的订单和邻接两个项目取决于您。
如果您的列表无序,您可以订购:
false
容易!