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

C# 从列表中提取连续的非空数字及其各自的起始和结束索引?,c#,.net,C#,.net,比如说,如果我有一个列表,看起来像null,null,2,3,4,null,null,null,3,3,null,我想提取连续的非null数字,以及它们各自相对于主列表的起始和结束索引-我该怎么做?结果应该是一个包含两个对象的列表,{startIndex=2,endIndex=4,list=[2,3,4]}和{startIndex=7,endIndex=8,list=[3,3]} 我正在尝试使用此代码,但它不起作用 refinedList是我的数据列表。我需要xBegin和xEnd,我应该根据边

比如说,如果我有一个
列表
,看起来像
null,null,2,3,4,null,null,null,3,3,null
,我想提取连续的非null数字,以及它们各自相对于主列表的起始和结束索引-我该怎么做?结果应该是一个包含两个对象的列表,
{startIndex=2,endIndex=4,list=[2,3,4]}
{startIndex=7,endIndex=8,list=[3,3]}

我正在尝试使用此代码,但它不起作用

refinedList
是我的数据列表。我需要
xBegin
xEnd
,我应该根据边界计算它们,并将数据传递给
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>();
            }
    }
}
var templast=newlist();
双xBegin=0;
对于(int i=0;i0)
如果(!refinedList[i-1].HasValue)
{
xBegin=矩形宽度*((nfloat)i/(data.Count-1));
}
Add(精简列表[i].Value);
}
其他的
{
如果(i>0)
if(精简列表[i-1].HasValue)
{
添加(DataPointsToLine(模板列表、矩形高度、xBegin、矩形宽度*((nfloat)(i-1)/(data.Count-1)));
tempList=新列表();
}
}
}

for(int i=0;i这个类如何封装结果:

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 int Start{get;set;}
公共int End{get;set;}
公共列表编号{get;set;}
公共子列表(整数开始、整数结束、列表编号)
{
开始=开始;
结束=结束;
数字=数字;
}
}
您可以按如下方式生成子列表:

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());
    }
}
公共静态IEnumerable FindNonNullRanges(列表编号)
{
int start=-1;
对于(int i=0;i=0)
{
收益返回新子列表(
开始
i-1,,
数字.Skip(start).Take(i-start.Cast().ToList());
}
开始=-1;
}
其他的
{
如果(开始<0)
开始=i;
}
}
如果(开始>=0)
{
收益返回新子列表(
开始
数字。计数-1,
number.Skip(start).Take(numbers.Count-start.Cast().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)}]");
    }
}
static void Main()
{
列表测试=新列表
{
空,空,2,3,4,空,空,3,3,空
};
foreach(FindNonNullRanges中的var子列表(测试))
{
Console.WriteLine($”从{sublist.Start}到{sublist.End}=[{string.Join(“,”,sublist.number)}]);
}
}
这将产生以下结果:

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

从7到8=[3,3]

我的版本:


这段代码与您的问题有什么关系?“它不起作用”-到底什么不起作用?这不会编译`if(refinedList[i-1].HasValue | | |)`为什么要使用rects?什么类型是
nfloat
?请参见编辑。@DanField这与此无关。希望这对您有所帮助,我在手机上。很难工作。很好,我现在就解决这个问题。
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)}]");
    }
}
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]