始终以最新数据的形式访问数据[0]

时间:2013-02-15 00:11:31

标签: c#

我有一个包含一百万个元素的数组,我将通过它将其作为实时数据进行模拟,将当前索引设为“正确”并将其递增以模拟新数据。

我将对现在的数据进行大量计算,而数据X则会过去。

我想知道是否有一种方便的方法来抽象它来访问someDataType [0]和1 bar前的今天的数据作为someDataType [1]等等?

我是编程新手,所以我不确定什么是什么,什么不可能。理想情况下,此数据类型不必将数据从数组复制到数据类型,而是可以存储所有数据本身并跳过数组或以某种方式指向数组。它肯定必须能够以与数组相同的方式访问数据,而不必迭代自己以获得像列表所需的某些点。

如果可以任何方式,形状或形式,我真的不知道。因此,我在问。感谢您的任何意见! :)

3 个答案:

答案 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,或者使该类具有通用性。