private String[] StringSpliter(String OriginalString) {
String newString = "";
for (String s: OriginalString.split("(?<=\\G.{"nth position"})")) {
if(s.length()<3)
newString += s +"/";
else
newString += StringSpliter(s) ;
}
return newString.split("/");
}
Вы можете добавить его как метод расширения:
public static T[] SubArray<T>(this T[] data, int index, int length)
{
T[] result = new T[length];
Array.Copy(data, index, result, 0, length);
return result;
}
static void Main()
{
int[] data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int[] sub = data.SubArray(3, 4); // contains {3,4,5,6}
}
Обновить повторное клонирование (что не было очевидным в исходном вопросе). Если вам действительно нужен глубокий клон; что-то вроде:
public static T[] SubArrayDeepClone<T>(this T[] data, int index, int length)
{
T[] arrCopy = new T[length];
Array.Copy(data, index, arrCopy, 0, length);
using (MemoryStream ms = new MemoryStream())
{
var bf = new BinaryFormatter();
bf.Serialize(ms, arrCopy);
ms.Position = 0;
return (T[])bf.Deserialize(ms);
}
}
Это действительно требует, чтобы объекты были сериализуемыми ( [Serializable]
или ISerializable
). Вы можете легко заменить любой другой сериализатор при необходимости - XmlSerializer
, DataContractSerializer
, protobuf-net и т. Д.
Обратите внимание, что глубокое клонирование сложно без сериализации; в частности, ICloneable
в большинстве случаев трудно доверять.
Я думаю, что код, который вы ищете:
Array.Copy (oldArray, 0, newArray, BeginIndex, EndIndex - BeginIndex)
В качестве альтернативы копированию данных вы можете создать оболочку, которая дает вам доступ к части исходного массива, как если бы она была копией части массива. Преимущество состоит в том, что вы не получаете еще одну копию данных в памяти, а недостатком являются небольшие накладные расходы при доступе к данным.
public class SubArray<T> : IEnumerable<T> {
private T[] _original;
private int _start;
public SubArray(T[] original, int start, int len) {
_original = original;
_start = start;
Length = len;
}
public T this[int index] {
get {
if (index < 0 || index >= Length) throw new IndexOutOfRangeException();
return _original[_start + index];
}
}
public int Length { get; private set; }
public IEnumerator<T> GetEnumerator() {
for (int i = 0; i < Length; i++) {
yield return _original[_start + i];
}
}
IEnumerator IEnumerable.GetEnumerator() {
return GetEnumerator();
}
}
Использование:
int[] original = { 1, 2, 3, 4, 5 };
SubArray<int> copy = new SubArray<int>(original, 2, 2);
Console.WriteLine(copy.Length); // shows: 2
Console.WriteLine(copy[0]); // shows: 3
foreach (int i in copy) Console.WriteLine(i); // shows 3 and 4
Array.ConstrainedCopy будет работать.
public static void ConstrainedCopy (
Array sourceArray,
int sourceIndex,
Array destinationArray,
int destinationIndex,
int length
)
Вы можете сделать это довольно легко;
object[] foo = new object[10];
object[] bar = new object[7];
Array.Copy(foo, 3, bar, 0, 7);
Вы можете использовать Array.Copy (...)
для копирования в новый массив после того, как вы его создали, но я не думаю, что существует метод, который создает новый массив , а копирует ряд элементов.
Если вы используете .NET 3.5, вы могли бы использовать LINQ:
I видите, что вы хотите делать клонирование, а не просто копировать ссылки.
В этом случае вы можете использовать .Select
для проецирования элементов массива в их клоны.
Например, если в ваших элементах реализован IClonable
, вы можете сделать что-то вроде этого:
var newArray = array.Skip(3).Take(5).Select(eachElement => eachElement.Clone()).ToArray();
Примечание. Для этого решения требуется .NET Framework 3.5.
Основываясь на ответе Марка, но добавляя желаемое поведение клонирования
public static T[] CloneSubArray<T>(this T[] data, int index, int length)
where T : ICloneable
{
T[] result = new T[length];
for (int i = 0; i < length; i++)
{
var original = data[index + i];
if (original != null)
result[i] = (T)original.Clone();
return result;
}
И если реализация ICloneable слишком похожа на тяжелую работу, то рефлексивная работа с использованием библиотеки Copyable Хаварда Страндена для выполнения требуется тяжелый подъем.
using OX.Copyable;
public static T[] DeepCopySubArray<T>(
this T[] data, int index, int length)
{
T[] result = new T[length];
for (int i = 0; i < length; i++)
{
var original = data[index + i];
if (original != null)
result[i] = (T)original.Copy();
return result;
}
Обратите внимание, что реализация OX.Copyable работает с любым из:
Тем не менее, чтобы автоматизированное копирование работало, одно из следующих утверждений должно выполняться, например:
- Его тип должен иметь конструктор без параметров или
- Он должен быть Копируемым, или
- Он должен иметь IInstanceProvider, зарегистрированный для его типа.
Таким образом, это должно охватывать практически любую вашу ситуацию. Если вы клонируете объекты, где подграф содержит такие вещи, как подключения к базе данных или файлы / потоки, у вас, очевидно, есть проблемы, но это верно для любой обобщенной глубокой копии.
Клонирование элементов в массиве не является чем-то универсальным. Вы хотите глубокое клонирование или простую копию всех членов?
Давайте выберем подход «наилучшего усилия»: клонирование объектов с использованием интерфейса ICloneable или двоичной сериализации:
public static class ArrayExtensions
{
public static T[] SubArray<T>(this T[] array, int index, int length)
{
T[] result = new T[length];
for (int i=index;i<length+index && i<array.Length;i++)
{
if (array[i] is ICloneable)
result[i-index] = (T) ((ICloneable)array[i]).Clone();
else
result[i-index] = (T) CloneObject(array[i]);
}
return result;
}
private static object CloneObject(object obj)
{
BinaryFormatter formatter = new BinaryFormatter();
using (MemoryStream stream = new MemoryStream())
{
formatter.Serialize(stream, obj);
stream.Seek(0,SeekOrigin.Begin);
return formatter.Deserialize(stream);
}
}
}
Это не идеальное решение, потому что просто существует ни один из них не будет работать для любого типа объекта.
Что касается клонирования, я не думаю, что сериализация вызывает ваши конструкторы. Это может нарушить инварианты классов, если вы делаете интересные вещи в ctor.
Кажется, более безопасным вариантом будет использование виртуальных методов клонирования, вызывающих конструкторы копирования.
protected MyDerivedClass(MyDerivedClass myClass)
{
...
}
public override MyBaseClass Clone()
{
return new MyDerivedClass(this);
}
Не существует единого метода, который бы делал то, что вы хотите. Вам нужно будет сделать метод клонирования доступным для класса в вашем массиве. Затем, если LINQ является опцией:
Foo[] newArray = oldArray.Skip(3).Take(5).Select(item => item.Clone()).ToArray();
class Foo
{
public Foo Clone()
{
return (Foo)MemberwiseClone();
}
}
Рассматривали ли вы возможность использования ArraySegment
?
Я думаю, что каждый профессиональный программист на C ++ должен иметь копию стандарта, на которую можно ссылаться. Но сесть и утомиться, прочитать от корки до корки, будет довольно ошеломляющим. В основном он написан для разработчиков (разработчиков компиляторов), и в нем почти нет объяснения причин, по которым стандарт требует определенных вещей.
Итак, я бы сказал, что для профессионального программиста на C ++ более важно иметь и читать:
Или, по крайней мере, какое-то приличное их подмножество. Если у вас за плечами кусок этих книг, вы
Как насчет использования Array.ConstrainedCopy :
int[] ArrayOne = new int[8] {1,2,3,4,5,6,7,8};
int[] ArrayTwo = new int[5];
Array.ConstrainedCopy(ArrayOne, 3, ArrayTwo, 0, 7-3);
Вы можете использовать Array.CopyTo :
int[] ArrayOne = new int[8] {1,2,3,4,5,6,7,8};
int[] ArrayTwo = new int[5];
ArrayOne.CopyTo(ArrayTwo,3); //starts copy at index=3 until it reaches end of
//either array
Я не уверен, насколько глубоко это действительно, но:
MyArray.Tolist
Это немного накладной, но это может вырезать ненужный метод.