我有一个
list<int> = {14, 24, 56,189,909,1000};
我想将它们折叠(分组?)一个范围,使得落在彼此范围内的整数折叠成一个值。
所以结果应该是范围= 100
{14,24,56} //since they 24 falls within 100 of 14 and 56 falls within 100 of 24
{189}
{909, 1000} //since they fall within 100 of each other
我知道这可以使用linq组,但是我被语法困扰了。
我看过这个answer,但无法弄清楚该范围的用途,因为我只有一个范围,即100。
int[] values = {100, 110, 120, 130, 140, 150, 160, 170};
int[] ranges = {115, 145, 180};
var query = from value in values
group value by ranges.Where(x => value >= x)
.DefaultIfEmpty()
.Last();
foreach (var group in query)
{
Console.WriteLine("{0}: {{{1}}}", group.Key,
string.Join(", ", group));
}
答案 0 :(得分:1)
编辑:这可能不适用,尤其是评论中的附加要求,因为它1)仅在一个点启动每个组,2)仅在第一个组中放置150个。
我可能会这样写,因为&#34;动态&#34;范围(并且我不确定如果没有同样涉及的桶处理,Group By如何使用)。此功能要求输入已经排序。
IEnumerable<IEnumerable<int>> GroupByStartingRange (IEnumerable<int> src) {
int? maybeStart;
while ((maybeStart = src.FirstOrDefault() != null) {
if (maybeStart.HasValue) {
var start = maybeStart.Value;
yield return src.TakeWhile(x => x <= start + 100)
src = src.SkipWhile(x => x <= start + 100);
}
}
}
答案 1 :(得分:1)
您最好的选择是使用普通的旧for循环而不是linq:
var l = new[] { 14, 24, 56, 189, 909, 1000 };
var groups = new List<List<int>>();
groups.Add(new List<int>());
groups[0].Add(l[0]);
for (int i = 1; i < l.Length; i++)
{
if (l[i] - l[i - 1] > 100)
{
groups.Add(new List<int>());
}
groups[groups.Count - 1].Add(l[i]);
}
答案 2 :(得分:0)
假设您的范围是有序的:
int[] values = { 100, 110, 120, 130, 140, 150, 160, 170 };
int[] ranges = { 115, 145, 180 };
var groups = values.GroupBy(x => ranges.First(r => x <= r));