Извлеките строки и столбцы из массива, используя другой массив строк и столбцов в качестве индекса [duplicate]

Другим случаем, когда NullReferenceExceptions может случиться, является (неправильное) использование оператора as :

class Book {
    public string Name { get; set; }
}
class Car { }

Car mycar = new Car();
Book mybook = mycar as Book;   // Incompatible conversion --> mybook = null

Console.WriteLine(mybook.Name);   // NullReferenceException

Здесь Book и Car являются несовместимыми типами; a Car не может быть преобразован / передан в Book. Когда этот сбой завершается неудачно, as возвращает null. Используя mybook после этого, вы вызываете NullReferenceException.

В общем случае вы должны использовать cast или as, как показано ниже:

Если вы ожидаете преобразования типа в всегда преуспевает (т. е. вы знаете, какой объект должен быть впереди времени), тогда вы должны использовать cast:

ComicBook cb = (ComicBook)specificBook;

Если вы не уверены в типе, но хотите попробовать , чтобы использовать его как определенный тип, затем используйте as:

ComicBook cb = specificBook as ComicBook;
if (cb != null) {
   // ...
}

8
задан gnovice 1 May 2010 в 21:13
поделиться

3 ответа

Если вы хотите избежать использования цикла for, это, вероятно, самый чистый способ сделать это:

indexCell = num2cell(indexmatrix, 1);
linearIndexMatrix = sub2ind(size(kDimensionalMatrix), indexCell{:});
finalTable = kDimensionalMatrix(linearIndexMatrix);

Первая строка помещает каждый столбец indexmatrix в отдельные ячейки ячейки с использованием num2cell . Это позволяет нам передавать все k столбцы в виде списка разделенных запятыми в sub2ind , функцию, которая преобразует индексы индексирования (строка , столбец и т. д.) в линейные индексы (каждый элемент матрицы пронумерован от 1 до N, N - общее число элементов в матрице). Последняя строка использует эти линейные индексы для замены цикла for. Хорошее обсуждение индексации матриц (нижний, линейный и логический) можно найти здесь здесь .

Еще немного пищи для размышлений ...

Тенденция чтобы уклониться от петель в пользу векторизованных решений, к чему привыкли многие пользователи MATLAB (включая меня). Однако более новые версии MATLAB обрабатывают цикл намного эффективнее. Как обсуждалось в , этот ответ на другой вопрос SO, использование для циклов может иногда приводить к более быстродействующему коду, чем вы могли бы получить с помощью векторизованного решения.

Я, конечно, НЕ говорю вы не должны пытаться больше векторизовать свой код, только чтобы каждая проблема была уникальной. Векторизация будет часто быть более эффективной, но не всегда . Для вашей проблемы скорость выполнения для циклов по сравнению с векторизованным кодом, вероятно, будет зависеть от того, насколько велики значения n и k.

15
ответ дан gnovice 27 August 2018 в 11:43
поделиться

Чтобы обрабатывать элементы вектора indexmatrix(row, :) как отдельные индексы, вам нужны элементы в виде массива ячеек. Итак, вы можете сделать что-то вроде этого

subsCell = num2cell( indexmatrix( row, : ) );
finalTable( row ) = kDimensionalMatrix( subsCell{:} );

Чтобы развернуть subscell как список, разделенный запятыми, вам, к сожалению, нужны две отдельные строки. Однако этот код не зависит от k.

6
ответ дан Edric 27 August 2018 в 11:43
поделиться
  • 1
    Большой! Можете ли вы получить его независимо от количества строк? – AnnaR 27 April 2009 в 12:52
  • 2
    @AnnaR - я только что опубликовал ответ, который обрабатывает все n строки из indexmatrix сразу. – Shai 5 December 2012 в 18:19

Преобразуйте свои подиндексы в линейные индексы хакерским способом

ksz = size(kDimensionalMatrix);
cksz = cumprod([ 1 ksz(1:end-1)] );
lidx = ( indexmatrix - 1 ) * cksz' + 1; #'
% lindx is now (n)x1 linear indices into kDimensionalMatrix, one index per row of indexmatrix
% access all n values:
selectedValues = kDimensionalMatrix( lindx );

Приветствия!

0
ответ дан Shai 27 August 2018 в 11:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: