始终将数据[0]作为最新数据访问
本文关键字:数据 最新 访问 | 更新日期: 2023-09-27 17:59:12
我有一个由一百万个元素组成的数组,我将把它作为实时数据运行,将当前索引设置为"现在",并将其递增以模拟新的数据。
我将对现在的数据和过去的X条数据进行大量计算。
我想知道是否有一种方便的方法可以将其抽象为访问someDataType[0]和1 bar前的someDataType[1]等今天的数据?
我是编程新手,所以我真的不确定什么是可能的,什么是不可能的。理想情况下,此数据类型不必将数据从数组复制到数据类型,而是可以存储所有数据本身并跳过数组或以某种方式指向数组。它肯定必须能够以与数组相同的方式访问数据,而不必像列表那样迭代到某个点。
我真的不知道这在任何方面、形状或形式上是否可能。所以我在问。感谢您的意见!:)
首先,如果您想添加新项,那么直接使用数组可能不是最好的选择(除非最新的项应该覆盖最旧的项)。一个更好的选择是List<T>
。
现在,您想要创建的是一个"反向"集合:它将包含一个List<T>
和:
- 其索引器将访问支持列表中的反向索引
- 其add方法(可能称为
AddFirst()
)将添加到列表的末尾 - 其
GetEnumerator()
方法将返回反向枚举器
随着所有这些需求的充实,代码几乎自己写:
class AddFirstList<T> : IEnumerable<T>, IReadOnlyList<T>
{
private readonly List<T> m_list = new List<T>();
public void AddFirst(T item)
{
m_list.Add(item);
}
public IEnumerator<T> GetEnumerator()
{
return Enumerable.Reverse(m_list).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public int Count
{
get { return m_list.Count; }
}
public T this[int index]
{
get { return m_list[Count - index - 1]; }
}
}
(如果您不在.Net 4.5上,请删除IReadOnlyList<T>
接口。)
听起来您需要对结构进行动态调整,因此在System.Collections.Generic命名空间中找到List<T>
是一个不错的选择。
var list = new List<int>();
list.Add(1); // keep adding
它提供了与数组一样的索引访问,但您可以根据需要不断添加元素。如果您只想快速检索最后一个元素(除了通过索引进行正常的随机访问),则可以使用针对IList<T>
接口(也是List<T>
实现的接口)优化的Last()
扩展方法直接返回最后一个元件,而无需枚举整个序列。
然而,听起来您想要的是更类似于完全反向索引访问的东西。为此,你可能必须对其进行编码。为了可重用性,你可以将其作为项目中的扩展方法,并在任何需要的地方使用。这样的方法应该适合你的需求。
public static class ListExtensions
{
public static T FromEnd<T>(this IList<T> list, int position)
{
if (list == null || list.Count == 0)
{
throw new ArgumentException("list cannot be null or empty");
}
return list[(list.Count - 1) - position];
}
}
而且使用它很简单。
var myList = new List<int>() { 1, 2, 3, 4, 5 };
int item = myList.FromEnd(1);
Debug.Assert(item == 4);
当然,这里的问题是,如果你想在foreach
中循环使用它(你仍然可以使用标准的for
),这就不适合了。如果使用foreach,您可以简单地循环使用foreach (var item in myList.Reverse()) { }
,也可以使用svick答案中编码的方法。
听起来您希望索引0是"当前数据",索引1是以前的数据。
您可以通过编写自己的类来实现这一点,该类封装了百万元素数组。然后,您可以指定right now
索引,并将其添加到每个索引中。例如:
public class DataArray
{
readonly Object[] data;
int rightNow;
public int RightNow
{
get { return this.rightNow; }
set { this.rightNow = value; }
}
public DataArrat(Object[] data)
{
// TODO: Check that data is not null.
this.data = data;
}
// This is called an 'indexer':
public Object this[int index]
{
get
{
// TODO: Check whether (index + this.rightNow) is in the valid range.
return this.data[index + this.rightNow];
}
}
}
现在你可以这样使用它,例如:
// Initialize the DataArray:
Object[] millionElementArray /* = from somewhere, e.g. */ = new []
{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
var data = new DataArray(millionElementArray);
// Start at bar 8:
data.RightNow = 8;
// Use the data:
Object currentData = data[0];
Object futureData = data[-1];
Object pastData = data[1];
// Go to the next bar:
data.RightNow--;
// Use the data:
Object currentData = data[0];
Object futureData = data[-1];
Object pastData = data[1];
// Rinse and repeat...
请注意,您应该用正在使用的数据类型替换Object
,或者使类成为泛型。