如何根据移动范围对整数列表进行分组?

时间:2014-09-29 22:02:47

标签: c# linq

我有一个

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));
    }

3 个答案:

答案 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));