Общий индекс для ступенчатых массивов
У меня есть массив arr[][], он ступенчатый, как я могу сделать, чтобы для доступа к его элементам нужен был только один индекс.
Пример:
Если взять индекс [1][2] == [5] или [0][3] == [3]
Ответы (3 шт):
Автор решения: timur
→ Ссылка
static class ArrayExtensions {
public static T GetValueAt<T>(this T[][] arr, int index) {
int currentIndex = 0;
foreach (T[] arr1 in arr) {
foreach (T i in arr1) {
if (currentIndex == index)
return i;
currentIndex++;
}
}
throw new IndexOutOfRangeException();
}
}
Использование:
int[][] arr = new int[][] { new int[] { 0, 1, 2, 3 }, new int[] { 4, 5, 6 } };
Console.WriteLine(arr.GetValueAt(5)); //=> 5
Автор решения: Aimon Z.
→ Ссылка
int[][] arr = new int[3][] { new int[] { 0, 1, 2, 3, 4 }, new int[] { 5, 6, 7, 8 }, new int[] { 9, 10, 11 } };
int i = 0;
for ( ; ; )
{
int ind = index;
if ((ind -= arr[i].Length) < 0)
{
break;
}
i++;
index = ind;
}
return arr[i][index];
Автор решения: Grundy
→ Ссылка
Стандартных механизмов, для решения этой задачи нет. А так же формула расчета индексов для прямоугольного массива тоже не подходит.
Решение может быть только одно: идти по массивы и считать элементы.
Реализация может быть в лоб:
arr.SelectMany(cur => cur)
.ElementAt(index)
Где SelectMany делает массив плоским, а ElementAt берет элемент по указанному индексу.
Улучшить можно, если не считать каждый элемент, а сразу оценивать в каком из массивов расположен элемент
static T ByIndex2<T>(T[][] arr, int index)
{
foreach (var item in arr)
{
if (index - item.Length < 0) // если разница меньше 0, значит нашли массив, а index соответствует индексу нужного элемента в найденном массиве
{
return item[index];
}
index -= item.Length;
}
throw new IndexOutOfRangeException(nameof(index));
}
