С помощью int arr[4][2]
в C++ я мог перебирать строки и столбцы, что идеально подходит практически для всего.
На C# я могу реализовать это так: int[10,10]. int[10][]
бесполезно, так как это неровный массив, а неровный массив мне не нужен.
Теперь мне нужно выбрать каждую строку и обработать каждую строку отдельно, если я хочу раздуть свой код блоками кода, которые точно описывают, как это сделать. Разве C# не должен быть обновлением C++ или, по крайней мере, более простым в использовании? Почему у меня не может быть простой матрицы?
Вместо того, чтобы делать arr[0].Sum()
для суммирования строки, мне нужно сделать что-то вроде arr.Take(y).Sum()
— создать по пути новый массив. Но вы не можете этого сделать, поскольку LINQ этого не поддерживает.
Единственный способ сделать это сейчас — List<List<int>>()
. Как вы с этим справляетесь?
@EduardG Что-нибудь в Span2D<T> выглядит так, как вы хотите?
@AndrewMorton кажется, что у меня нет к этому доступа, возможно, потому, что я использую .NET Framework 4.7.2. Пытаюсь выяснить, где его найти... Хотя у меня есть Span<T>.
@EduardG Похоже, вам просто придется использовать циклы for
?
Есть ли в C++ разница между двумерными массивами и массивами массивов? Если суть задаваемого вопроса заключается в том, как сделать на C# что-то, что было бы легко на C++, то одного только синтаксиса может быть недостаточно для сравнения, поскольку то, что кажется одним и тем же синтаксисом на разных языках, может означать очень разные вещи. «Как ты с этим справляешься?» - Концептуально разделив эти два понятия и используя наиболее подходящую структуру для решения поставленной задачи. И похоже, что задача здесь — использовать массив массивов с линейным доступом, а не двумерный массив с доступом к множествам.
@AndrewMorton Как выбрать все 10 элементов из строки 0 из [50,10]? Кажется, нет практического пути. Я хочу сделать «var row0Sum = Sum(array[0])». В цикле for мне пришлось бы суммировать их один за другим, что непрактично для моих нужд, поскольку сумма в моем случае — дорогостоящая операция. Вместо этого мне нужно объявить новый массив для хранения каждой строки и заполнить его, используя исходный массив через цикл for, и только затем передать его функции Sum.
"Метод ArrayExtensions.GetColumn<T>(T[][], Int32)" ссылка
@Дэвид, да, меня забавляет то, что в C# отсутствует основополагающий фрагмент кода и математическая логика. Это простая матрица, и C# не может ее представить. Задача состоит в том, чтобы эффективно объявить матрицу строк и столбцов, а затем передать каждую строку функции, запуск которой требует больших затрат (поэтому ее нельзя запускать для каждого отдельного элемента, но это нужно делать построчно). . Чтобы сделать это, мне нужно запустить другой дорогостоящий алгоритм для выделения нового массива для представления моих строк вместо использования значений в уже существующем массиве [,].
@rotabor Я использую .NET Framework, а Microsoft.Toolkit ArrayExtensions — это устаревший пакет, который я предпочитаю не добавлять в свое решение для последовательного обхода массива. Причина, по которой я использую .NET, заключается в том, что мне нужен низкоуровневый доступ к API Win32 с помощью PInvoke, который не поддерживается в .NET Core из-за его многоплатформенной совместимости.
Вместо этого я решил использовать массивы Jagged, поэтому [x][]. Я не могу с этим синтаксисом и необходимостью выделять каждую отдельную строку в X, но более элегантного решения, похоже, не существует.
@EduardG Мне кажется, вы недостаточно подробно описали проблему в вопросе. Например, почему вам нужно использовать Sum
вместо +
?
@EduardG P/Invoke не исключается .NET [Core]: Platform Invoke (P/Invoke).
«что я предпочитаю не добавлять в свое решение» — добавьте только то, что вам нужно.
Этот вопрос был соответствующим образом отредактирован. Мы занимаемся проблемами программирования, а не чувствами, и все остальное — это просто метакомментарии и отвлечение от реальной проблемы, которая у вас есть. Размещенные здесь вопросы и ответы предназначены не только для задающего вопроса, но и для помощи другим, столкнувшимся с такой же проблемой. Краткие вопросы помогают другим быстрее понять, является ли их проблема той же самой.
@DalijaPrasnikar это очень черно-белое, большая часть вашей логики основана на чувствах, хотите верьте, хотите нет, конечно, гораздо больше, чем вы думаете. Я просто осознаю это и проливаю на это свет, так что мы осознаем, а не невежественны. Разделять эти два понятия — просто невежество, особенно при построении сообщества. В любом случае я очень обижаюсь на то, что мои слова редактируют без моего разрешения и удаляют мои комментарии. Я чувствую себя угнетенным.
Может быть, просто используйте эту функцию stackoverflow.com/a/73373888/14868997 , чтобы создать Span
. Я согласен, что не стоит вовлекаться эмоционально. Будьте беспристрастны и анализируйте проблему, не волнуясь. Что касается чувства угнетения: см. youtube.com/watch?v=YAA-G947ofg
См. также этот пакет github.com/VictorNicollet/NoAlloq для LINQ для спанов. Или вы можете создать свои собственные методы расширения.
От Тим-Мэйс. Добавьте методы для многомерных массивов
public static T[] GetRow<T>(this T[,] array, int row)
{
var rowLength = array.GetLength(1);
var result = new T[rowLength];
for (int i = 0; i < rowLength; i++)
{
result[i] = array[row, i];
}
return result;
}
Создавать новый массив для каждого доступа крайне неэффективно.
Я выбрал это в качестве ответа @Charlieface, так как, к сожалению, я не нашел способа сделать это без создания нового массива. В итоге я сам использовал неровные массивы. Позор C#.
Я сильно подозреваю, что вы получите более полезные ответы, если уберете из вопроса некоторые гиперболы и вместо этого предоставите требования. (Наиболее подходящий способ достижения того, что вам нужно, действительно будет зависеть от части «что вам нужно»...)