我有一个包含一百万个元素的数组,我将通过它将其作为实时数据进行模拟,将当前索引设为“正确”并将其递增以模拟新数据。
我将对现在的数据进行大量计算,而数据X则会过去。
我想知道是否有一种方便的方法来抽象它来访问someDataType [0]和1 bar前的今天的数据作为someDataType [1]等等?
我是编程新手,所以我不确定什么是什么,什么不可能。理想情况下,此数据类型不必将数据从数组复制到数据类型,而是可以存储所有数据本身并跳过数组或以某种方式指向数组。它肯定必须能够以与数组相同的方式访问数据,而不必迭代自己以获得像列表所需的某些点。
如果可以任何方式,形状或形式,我真的不知道。因此,我在问。感谢您的任何意见! :)
答案 0 :(得分:4)
首先,如果要添加新项目,则直接使用数组可能不是最佳选择(除非最新项目应覆盖最旧的项目)。更好的选择是List<T>
。
现在,您要创建的是“反向”集合:它将包含List<T>
和:
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>
界面。)
答案 1 :(得分:0)
听起来您需要在结构上进行动态调整,因此在System.Collections.Generic命名空间中找到一个很好的选择List<T>
。
var list = new List<int>();
list.Add(1); // keep adding
它提供索引访问,就像数组一样,但您可以根据需要继续添加元素。如果您想要做的就是快速检索最后一个元素(除了通过索引进行正常的随机访问),您可以使用Last()
扩展方法which is optimized作为IList<T>
接口(以及List<T>
实现的)直接返回最后一个元素而不需要枚举整个序列。
然而,听起来你想要的东西更像是完全反向索引访问。为此,您可能需要对其进行编码。为了可重用,您可以在项目中将其作为扩展方法,并在需要的地方使用它。这样的事情应该符合你的需要。
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答案中编码的方法。
答案 2 :(得分:0)
听起来你希望索引0成为'当前数据',索引1成为以前的数据。
您可以通过编写自己的封装了million-element数组的类来实现此目的。然后,您可以指定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
,或者使该类具有通用性。