如何从C#中的现有数组中获取子数组而不进行复制?

时间:2021-06-23 21:36:03

My question is similar to Getting a sub-array from an existing array although a little different notion is very important in my case - I can't use memory copying.

我的问题类似于从现有数组中获取子数组,尽管在我的情况下,一点点不同的概念非常重要 - 我不能使用内存复制。

Let's say I have array X of 10000 elements, I need array Y that would contains 9000 elements from X, starting from X's index 500.

假设我有10000个元素的数组X,我需要数组Y包含X中的9000个元素,从X的索引500开始。

But I don't want to copy part of X to new array Y, so I don't want to use Array.Copy, Array.Clone, System.Block.Copy, IEnumerables etc. I want Y to be reference to X - Y[0] would be in fact X[500], Y[1] corresponds to X[501], ..., Y[9000] is X[9500].

但我不想将X的一部分复制到新的数组Y,所以我不想使用Array.Copy,Array.Clone,System.Block.Copy,IEnumerables等。我希望Y引用X - Y [0]实际上是X [500],Y [1]对应于X [501],...,Y [9000]是X [9500]。

Thus, for example changing value of X[100] would at the same time change value of Y[600]. How can I achieve this in C#?

因此,例如,改变X [100]的值将同时改变Y [600]的值。我怎样才能在C#中实现这一目标?

3 个解决方案

#1


7  

You could wrap it in another object with something like this:

您可以使用以下内容将其包装在另一个对象中:

class View<T>
{
     private T[] _array;
     private long _start;
     private long _length;
     public View(T[] array, long start, long length) { ... }
     public T this[long index] 
     {
         get 
         {
             if (/*do bounds check here*/) 
             {
                 return _array[_start + index];
             }    
         }
     }
}

This won't be an array, but a projection of one.

这不是一个数组,而是一个数组的投影。

#2


2  

You can use an ArraySegment. Here's an example:

您可以使用ArraySegment。这是一个例子:

String[] X = { "one", "two", "three", "four", "five"};

ArraySegment<String> arraySegment = new ArraySegment<String>(X, 1,3); // will contain {"two", "three", "four"}
arraySegment.Array[arraySegment.Offset + 1] = "3"; // X will contain { "one", "two", "3", "four", "five"};
                             // and arraySegment.Array will contain {"two", "3", "four"}

#3


0  

Sadly ArraySegment<T> is sealed, else you could easily have extended it with the proper array-syntax, ie indexers and the likes.

遗憾的是,ArraySegment 是密封的,否则您可以使用正确的数组语法(即索引器等)轻松扩展它。

If I were you I would go with ArraySegment<T> and if it doesn't have the proper requirements, like ElementAt(n) being to inefficient, just implement a better implementation. Ex:

如果我是你,我会使用ArraySegment ,如果它没有正确的要求,比如ElementAt(n)效率低下,只需实现更好的实现。例如:

public static class ArrayExtensions 
{
  // Getter using underlying array
  public static T GetValueAt<T>(this ArraySegment<T> array, int index)
  { // No safe checks here, would recommend them in production though
    return array.Array[array.Offset + index];
  }
  // Setter using underlying array
  public static void SetValueAt<T>(this ArraySegment<T> array, int index, T value)
  { // maybe we should check that the calculated index is valid? Or just blow up?
    array.Array[array.Offset + index] = value;
  }
}

#1


7  

You could wrap it in another object with something like this:

您可以使用以下内容将其包装在另一个对象中:

class View<T>
{
     private T[] _array;
     private long _start;
     private long _length;
     public View(T[] array, long start, long length) { ... }
     public T this[long index] 
     {
         get 
         {
             if (/*do bounds check here*/) 
             {
                 return _array[_start + index];
             }    
         }
     }
}

This won't be an array, but a projection of one.

这不是一个数组,而是一个数组的投影。

#2


2  

You can use an ArraySegment. Here's an example:

您可以使用ArraySegment。这是一个例子:

String[] X = { "one", "two", "three", "four", "five"};

ArraySegment<String> arraySegment = new ArraySegment<String>(X, 1,3); // will contain {"two", "three", "four"}
arraySegment.Array[arraySegment.Offset + 1] = "3"; // X will contain { "one", "two", "3", "four", "five"};
                             // and arraySegment.Array will contain {"two", "3", "four"}

#3


0  

Sadly ArraySegment<T> is sealed, else you could easily have extended it with the proper array-syntax, ie indexers and the likes.

遗憾的是,ArraySegment 是密封的,否则您可以使用正确的数组语法(即索引器等)轻松扩展它。

If I were you I would go with ArraySegment<T> and if it doesn't have the proper requirements, like ElementAt(n) being to inefficient, just implement a better implementation. Ex:

如果我是你,我会使用ArraySegment ,如果它没有正确的要求,比如ElementAt(n)效率低下,只需实现更好的实现。例如:

public static class ArrayExtensions 
{
  // Getter using underlying array
  public static T GetValueAt<T>(this ArraySegment<T> array, int index)
  { // No safe checks here, would recommend them in production though
    return array.Array[array.Offset + index];
  }
  // Setter using underlying array
  public static void SetValueAt<T>(this ArraySegment<T> array, int index, T value)
  { // maybe we should check that the calculated index is valid? Or just blow up?
    array.Array[array.Offset + index] = value;
  }
}