Подмножество массива в С#
Если у меня есть массив с 12 элементами, и я хочу, чтобы новый массив сбрасывал первый и 12-й элементы. Например, если мой массив выглядит так:
__ __ __ __ __ __ __ __ __ __ __ __
a b c d e f g h i j k l
__ __ __ __ __ __ __ __ __ __ __ __
Я хочу либо преобразовать его, либо создать новый массив, который выглядит как
__ __ __ __ __ __ __ __ __ __
b c d e f g h i j k
__ __ __ __ __ __ __ __ __ __
Я знаю, что могу сделать это, итерации над ними. Мне просто интересно, был ли более чистый способ встроен в С#.
** ОБНОВЛЕНО ДЛЯ ИСПРАВЛЕНИЯ ТИПО. Изменено 10 элементов на 12 элементов.
Ответы
Ответ 1
LINQ твой друг. :)
var newArray = oldArray.Skip(1).Take(oldArray.Length - 2).ToArray();
Несколько менее эффективно, чем создание массива вручную и его перебор, конечно, но гораздо проще...
Немного длиннее метод, который использует Array.Copy
заключается в следующем.
var newArray = new int[oldArray.Count - 2];
Array.Copy(oldArray, 1, newArray, 0, newArray.Length);
Ответ 2
Linq все приятный и увлекательный, но если вы ищете 1-лайнер, вы можете просто скомпоновать свои собственные служебные функции:
static class ArrayUtilities
{
// create a subset from a range of indices
public static T[] RangeSubset<T>(this T[] array, int startIndex, int length)
{
T[] subset = new T[length];
Array.Copy(array, startIndex, subset, 0, length);
return subset;
}
// create a subset from a specific list of indices
public static T[] Subset<T>(this T[] array, params int[] indices)
{
T[] subset = new T[indices.Length];
for (int i = 0; i < indices.Length; i++)
{
subset[i] = array[indices[i]];
}
return subset;
}
}
Итак, вы можете сделать следующее:
char[] original = new char[] { 'a', 'b', 'c', 'd', 'e', 'f', 'g' };
// array containing 'b' - 'f'
char[] rangeSubset = original.RangeSubset(1, original.Length - 2);
// array containing 'c', 'd', and 'f'
char[] specificSubset = original.Subset(2, 3, 5);
Ответ 3
Вы можете сделать это с помощью Array.Copy
или LINQ.
var letters = string[] { "a", "b", "c", "d", "e", "f", "g", "h", "i" };
int length = letters.Length - 2;
var items = new string[length];
Array.Copy(letters, 1, items, 0, length);
// or
var items = letters.Skip(1).Take(length).ToArray();
Ответ 4
Вы можете использовать структуру ArraySegment<T>
, как показано ниже:
var arr = new[] { 1, 2, 3, 4, 5 };
var offset = 1;
var count = 2;
var subset = new ArraySegment<int>(arr, offset, count)
.ToArray(); // output: { 2, 3 }
Отметьте здесь метод расширения, который использует его еще проще.
Ответ 5
Array.Copy() сделает это за вас, но вам все равно нужно создать новый массив с правильным размером.
Ответ 6
string[] s = initialize the array...
var subset = s.Skip(1).Take(s.Length - 2).ToArray();
Ответ 7
Если вы хотите избежать ручного индексирования массива. Не пытайтесь вытащить запрос в любом месте:
var newArray = oldArray.Skip(1).Reverse().Skip(1).Reverse().ToArray()
Ответ 8
С# 8 имеет тип Range
и Index
char[] a = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l' };
Index i1 = 1; // number 1 from beginning
Index i2 = ^1; // number 1 from end
var slice = a[i1..i2]; // { 'b','c','d','e','f','g','h','i','j' }