C# 从列表中获取前n个元素

C# 从列表中获取前n个元素,c#,C#,给定一个集合,我想迭代每个元素并检索前面的N个元素 数据集非常小(最多一百个元素)。可读性是首要考虑的问题 伪代码 var values = new List<decimal> { 1m, 1.5m, 2m, 2.5m, 3.0m, 3.5m, 4m, 4.5m, 5m }; var previousElementsCount = 3; for (var currentIndex = 0; currentIndex < values.Co

给定一个集合,我想迭代每个元素并检索前面的N个元素

数据集非常小(最多一百个元素)。可读性是首要考虑的问题

伪代码

var values = new List<decimal>
{
  1m,
  1.5m,
  2m,
  2.5m,
  3.0m,
  3.5m,
  4m,
  4.5m,
  5m
};

var previousElementsCount = 3;

for (var currentIndex = 0; currentIndex < values.Count - 1; currentIndex++)
{

  var range = values.GetPreviousElements(currentIndex, previousElementsCount);

  //currentIndex:0, result: []
  //currentIndex:1: result: [1]
  //currentIndex:2: result: [1.5, 1]
  //currentIndex:3: result: [2, 1.5, 1]
  //currentIndex:4: result: [2.5, 2, 1.5]
  //currentIndex:5: result: [3, 2.5, 2]
  // etc...
}

public static class ListExtensions 
{
  public static List<T> GetPreviousElements<T>(this List<T> list, int index, int previousElementsCount)
  {
    // ?
  }
}
var值=新列表
{
100万,
1.5米,
200万,
2.5米,
3.0米,
3.5米,
400万,
4.5米,
5米
};
var previousElementsCount=3;
对于(var currentIndex=0;currentIndex
如何实现
GetPreviousElements


谢谢

您可以使用下面这样的方法来获取前面的元素(最多3个),然后反过来满足您的需求。不是最理想的解决方案,但适用于相当小的
列表

编辑: 下面是另一种方法,使用前面的索引并返回到三个元素以获取值:

var values = new List<decimal>
{
  1m,
  1.5m,
  2m,
  2.5m,
  3.0m,
  3.5m,
  4m,
  4.5m,
  5m
};

var previousElementsCount = 3;

for (var currentIndex = 0; currentIndex < values.Count; currentIndex++)
{
    var previousElements = new List<decimal>();

    if (currentIndex > 0)
    {
        var count = currentIndex - previousElementsCount < 0 ? 0 : currentIndex - previousElementsCount;

        for (var x = currentIndex - 1; x >= 0 && x >= count; x--)
        {
            previousElements.Add(values[x]);
        }
    }

    Console.WriteLine($"currentIndex:{currentIndex}: result: [{string.Join(",", previousElements.Select(x => x.ToString()).ToArray())}]");            
}
var值=新列表
{
100万,
1.5米,
200万,
2.5米,
3.0米,
3.5米,
400万,
4.5米,
5米
};
var previousElementsCount=3;
对于(var currentIndex=0;currentIndex0)
{
var count=currentIndex-PreviousElementScont<0?0:currentIndex-PreviousElementScont;
对于(var x=currentIndex-1;x>=0&&x>=count;x--)
{
添加(值[x]);
}
}
Console.WriteLine($“currentIndex:{currentIndex}:结果:[{string.Join(“,”,previousElements.Select(x=>x.ToString()).ToArray())}]”;
}

这里有另一个想法,但基本上是相同的:

var values = new List<decimal> { 1m, 1.5m, 2m, 2.5m, 3.0m, 3.5m, 4m, 4.5m, 5m };

var previousElementsCount = 3;

for (var currentIndex = 0; currentIndex < values.Count - 1; currentIndex++)
{
    int count = currentIndex >= previousElementsCount ? previousElementsCount : currentIndex;
    var range = values.GetRange(currentIndex - count, count);
    range.Reverse();
}
var值=新列表{1m、1.5m、2m、2.5m、3.0m、3.5m、4m、4.5m、5m};
var previousElementsCount=3;
对于(var currentIndex=0;currentIndex=PreviousElementScont?PreviousElementScont:currentIndex;
var range=values.GetRange(currentIndex-count,count);
range.Reverse();
}

这真的毫无意义这里有什么问题?你不需要排队。看起来您已经解决了这个问题。
List
的当前实现由一个数组支持。如果您愿意依赖于实现细节,您可以利用它。或者,如果N级别为常量N(每个实例),那么您应该构建一个简单的
IList
实现,其中包含一个列表和一个固定大小的小集合,用于旋转最后N个元素through@MarcoSalerno好的,哪一部分没有意义,我能澄清什么?简单地说这没有意义,对我来说没有帮助。@robbpriestley不,它没有解决…List GetRange没有实现,它接受一个索引,一个从给定索引返回先前元素的计数。我已经更新了示例,希望能够消除实际阅读问题并提供答案时的歧义!:)<代码>变量计数=数学最大值(0,currentIndex-previousElementsCount)
@AhmedAbdelhameed Yep,这稍微简化了逻辑。@user2966445请注意,
count
在这种情况下是一个误导性的变量名,因为它不是“已使用”元素的计数。@AhmedAbdelhameed显然这段代码有很多地方需要清理。我在几分钟内把它组合起来,以帮助OP至少想出一个可行的解决方案。
var values = new List<decimal>
{
  1m,
  1.5m,
  2m,
  2.5m,
  3.0m,
  3.5m,
  4m,
  4.5m,
  5m
};

var previousElementsCount = 3;

for (var currentIndex = 0; currentIndex < values.Count; currentIndex++)
{
    var previousElements = new List<decimal>();

    if (currentIndex > 0)
    {
        var count = currentIndex - previousElementsCount < 0 ? 0 : currentIndex - previousElementsCount;

        for (var x = currentIndex - 1; x >= 0 && x >= count; x--)
        {
            previousElements.Add(values[x]);
        }
    }

    Console.WriteLine($"currentIndex:{currentIndex}: result: [{string.Join(",", previousElements.Select(x => x.ToString()).ToArray())}]");            
}
var values = new List<decimal> { 1m, 1.5m, 2m, 2.5m, 3.0m, 3.5m, 4m, 4.5m, 5m };

var previousElementsCount = 3;

for (var currentIndex = 0; currentIndex < values.Count - 1; currentIndex++)
{
    int count = currentIndex >= previousElementsCount ? previousElementsCount : currentIndex;
    var range = values.GetRange(currentIndex - count, count);
    range.Reverse();
}