从列表中提取连续的非空数字及其各自的起始和结束索引?

时间:2017-03-07 16:05:24

标签: c# .net

说,如果我有List<double?>看起来像null, null, 2, 3, 4, null, null, 3, 3, null并且我想提取连续的非空数字及其相应的主列表的起始和结束索引 - 我该怎么做?结果应该是包含两个对象的列表{ startIndex = 2, endIndex = 4, list = [ 2, 3, 4 ] }{ startIndex = 7, endIndex = 8, list = [ 3, 3 ] }

我试图使用此代码,但它无法正常工作

refinedList是我的数据列表。我需要xBeginxEnd,我应该根据边界计算它们并将数据传递给DataPointsToLine方法 - 这是我的最终目标。我简化并概括了上述案例。

var tempList = new List<double>();
double xBegin = 0;

for (int i = 0; i < refinedList.Count; i++)
{
    if (refinedList[i].HasValue)
    {
        if (i > 0)
            if (!refinedList[i - 1].HasValue)
            {
                xBegin = rect.Width * ((nfloat)i / (data.Count - 1));
            }
        tempList.Add(refinedList[i].Value);
    }
    else
    {
        if (i > 0)
            if (refinedList[i - 1].HasValue)
            {
                result.Add(DataPointsToLine(tempList, rect.Height, xBegin, rect.Width * ((nfloat)(i - 1) / (data.Count - 1))));
                tempList = new List<double>();
            }
    }
}

3 个答案:

答案 0 :(得分:2)

这个类如何封装结果:

public sealed class Sublist
{
    public int Start { get; set; }
    public int End   { get; set; }

    public List<double> Numbers { get; set; }

    public Sublist(int start, int end, List<double> numbers)
    {
        Start   = start;
        End     = end;
        Numbers = numbers;
    }
}

您可以像这样生成子列表:

public static IEnumerable<Sublist> FindNonNullRanges(List<double?> numbers)
{
    int start = -1;

    for (int i = 0; i < numbers.Count; ++i)
    {
        if (!numbers[i].HasValue)
        {
            if (start >= 0)
            {
                yield return new Sublist(
                    start,
                    i - 1,
                    numbers.Skip(start).Take(i - start).Cast<double>().ToList());
            }

            start = -1;
        }
        else
        {
            if (start < 0)
                start = i;
        }
    }

    if (start >= 0)
    {
        yield return new Sublist(
            start,
            numbers.Count-1,
            numbers.Skip(start).Take(numbers.Count - start).Cast<double>().ToList());
    }
}

还有一些测试代码:

static void Main()
{
    List<double?> test = new List<double?>
    {
        null, null, 2, 3, 4, null, null, 3, 3, null
    };

    foreach (var sublist in FindNonNullRanges(test))
    {
        Console.WriteLine($"From {sublist.Start} to {sublist.End} = [{string.Join(", ", sublist.Numbers)}]");
    }
}

这输出以下内容:

  

从2到4 = [2,3,4]

     

从7到8 = [3,3]

答案 1 :(得分:2)

我的版本DotNetFiddle.Net Example

using System;
using System.Linq;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        var list = new List<Double?> { null, null, 2, 3, 4, null, null, 3, 3, null };
        var groupLists = new List<GroupList>();
        GroupList currentGroupList = null;

        for (var i = 0; i < list.Count; i++)
        {
            if (list.ElementAt(i).HasValue)
            {
                if (currentGroupList == null)
                {
                    currentGroupList = new GroupList();
                    currentGroupList.Start = i;
                    groupLists.Add(currentGroupList);
                }
                currentGroupList.Items.Add(list.ElementAt(i).Value);
            }
            else
            {
                if (currentGroupList != null)
                {
                    currentGroupList.End = i -1;
                }
                currentGroupList = null;
            }
        }
        if (currentGroupList != null)
        {
            currentGroupList.End = list.Count -1;
        }



        foreach(var groupList in groupLists)
        {
            Console.WriteLine("{0} {1} [{2}]", groupList.Start, groupList.End, string.Join(",",groupList.Items.ToArray()));
        }
    }

    public class GroupList
    {
        public GroupList()
        {
            Items = new List<Double>();
        }

        public int Start { get; set; }
        public int End { get; set; }
        public List<Double> Items { get; set; }
    }
}

输出:

2 4 [2,3,4]
7 8 [3,3]

答案 2 :(得分:0)

for(int i=0; i<refinedList.Count;i++){
        if(refinedList[i].HasValue)
       {
          //setup start index
          while(refinedList[i].HasValue && i<refinedList.Count)
           //add items to list
          i++;
       }
        //Setup end index
}