C# 从没有间隙的对象列表中获取范围:
给定一个包含数千个对象的列表,如下所示:C# 从没有间隙的对象列表中获取范围:,c#,.net,linq,C#,.net,Linq,给定一个包含数千个对象的列表,如下所示: 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
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 });
var list=newlist();
添加(新的点地址{Line=1,Number=100f});
添加(新的点地址{Line=1,Number=101f});
添加(新的点地址{Line=1,Number=105f});
添加(新的点地址{Line=1,Number=106f});
添加(新的点地址{Line=2,Number=103f});
添加(新的点地址{Line=2,Number=104f});
创建无间隙范围(基于数字属性)的最佳方法是什么?
如果数字属性中的差异大于1,则为间隙,数字应位于不同的组中
第一组
行=1,数=100f行=1,数=101f 第2组 行=1,数=105f
行=1,数=106f 第3组 行=2,数=103f
线条=2,数字=104f 基本上,如果间隙>1,则应在不同的分组中
如果行不同,则它是不同的组。如果数字是相邻的数字,且行是相同的,则它必须位于同一组中,如示例所示。第1行被分为2组-第1组和第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 ;
}
}
轻松点 为什么
103.0。。104.1
是否不被视为差距?什么是“差距”?你指的是差距,差距小于2?所以100.0和102.0有一个间隙,但100.0和101.9没有间隙?还有两条记录没有“间隙”,但行的编号不同,它们是否分组在一起@Sadek我的钱是在两个数字之间的差上,或者四舍五入,或者被截断,而数字是>1
是一个缺口,所以100.4。。102.1将有一个。但在我们得到更多信息之前,这只是一个猜测。1.1。。2.2
考虑间隙,因为其距离为1.1?此外,您还应该输入“1的差值被认为是数字属性中的一个缺口”之类的信息。在回答问题时,不要将其作为注释。@ScottChamberlain他更改了问题,将所有数字设为int,因此可能只对相邻的数进行分组。用户2934236,您的意思是,如果您按数字对列表进行排序,然后对任何两个相邻的列表进行遍历和拆分,并且差异大于1,您将按照您希望的方式组织它们?酷。谢谢我会试试的。效果很好。伟大的解决方案!
List<PointAddress> addressList = GetSomeEnormousList() ;
List<List<PointAddress>> ranges = addressList
.Partition( (prev,curr) => curr.Line == prev.Line && curr.Number - prev.Number == 1.0 )
.ToList()
;
List<List<PointAddress>> ranges = addressList
.OrderBy( x => x.Line )
.ThenBy( x => x.Number )
.Partition( (prev,curr) => curr.Line == prev.Line && curr.Number - prev.Number == 1.0 )
.ToList() ;