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
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
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;
}
}