exponenta event banner

Списки, разделенные запятыми

Что такое список, разделенный запятыми?

Ввод ряда чисел, разделенных запятыми, дает то, что называется списком, разделенным запятыми. Программное обеспечение MATLAB ® возвращает каждое значение по отдельности:

1,2,3
ans =

     1


ans =

     2


ans =

     3

Такой список сам по себе не очень полезен. Но при использовании с большими и более сложными структурами данных, такими как структуры MATLAB и массивы ячеек, список, разделенный запятыми, позволяет упростить код MATLAB.

Создание списка, разделенного запятыми

В этом разделе описывается, как создать список, разделенный запятыми, из массива ячеек или структуры MATLAB.

Создание списка из массива ячеек

Извлечение нескольких элементов из массива ячеек дает список, разделенный запятыми. При наличии массива ячеек 4 на 6, как показано здесь

C = cell(4,6);
for k = 1:24
    C{k} = k*2;
end
C
C = 

    [2]    [10]    [18]    [26]    [34]    [42]
    [4]    [12]    [20]    [28]    [36]    [44]
    [6]    [14]    [22]    [30]    [38]    [46]
    [8]    [16]    [24]    [32]    [40]    [48]

при извлечении пятого столбца создается следующий список, разделенный запятыми:

C{:,5}
ans =

    34


ans =

    36


ans =

    38


ans =

    40

Это то же самое, что явно вводить

C{1,5},C{2,5},C{3,5},C{4,5}

Создание списка из структуры

Для структур извлечение поля структуры, которое существует в одном из ее измерений, дает список, разделенный запятыми.

Начните с преобразования массива ячеек, использованного выше, в структуру MATLAB 4 на 1 с шестью полями: f1 через f6. Поле чтения f5 для всех строк и MATLAB возвращает список, разделенный запятыми:

S = cell2struct(C,{'f1','f2','f3','f4','f5','f6'},2);
S.f5
ans =

    34


ans =

    36


ans =

    38


ans =

    40

Это то же самое, что явно вводить

S(1).f5,S(2).f5,S(3).f5,S(4).f5

Назначение выходных данных из списка, разделенного запятыми

Любой или все последовательные элементы списка, разделенного запятыми, можно назначить переменным с помощью простого оператора назначения. Использование массива ячеек C из предыдущего раздела назначьте переменным первую строку c1 через c6:

C = cell(4,6);
for k = 1:24
    C{k} = k*2;
end
[c1,c2,c3,c4,c5,c6] = C{1,1:6};
c5
c5 =

    34
Если указано меньшее количество выходных переменных, чем количество выходных данных, возвращаемых выражением, MATLAB присваивает первые N выходных данных этим N переменным, а затем отбрасывает оставшиеся выходные данные. В следующем примере MATLAB присваивает C{1,1:3} к переменным c1, c2, и c3, а затем отбрасывает C{1,4:6}:
[c1,c2,c3] = C{1,1:6};
Структурные выходы можно присвоить таким же образом:
S = cell2struct(C,{'f1','f2','f3','f4','f5','f6'},2);
[sf1,sf2,sf3] = S.f5;
sf3
sf3 =

    38
Вы также можете использовать deal функция для этой цели.

Назначение списку, разделенному запятыми

Самый простой способ назначить несколько значений списку, разделенному запятыми, - использовать deal функция. Эта функция распределяет все свои входные аргументы по элементам списка, разделенного запятыми.

В этом примере используется deal для перезаписи каждого элемента в списке, разделенном запятыми. Сначала создайте список.

c{1} = [31 07]; 
c{2} = [03 78];
c{:}
ans =

    31     7


ans =

     3    78

Использовать deal для перезаписи каждого элемента в списке.

[c{:}] = deal([10 20],[14 12]);
c{:}
ans =

    10    20


ans =

    14    12

В этом примере выполняется то же, что и в приведенном выше примере, но с разделенным запятыми списком векторов в поле структуры:

s(1).field1 = [31 07];
s(2).field1 = [03 78];
s.field1
ans =

    31     7


ans =

     3    78

Использовать deal для перезаписи полей структуры.

[s.field1] = deal([10 20],[14 12]);
s.field1
ans =

    10    20


ans =

    14    12

Использование списков, разделенных запятыми

Общие способы использования списков, разделенных запятыми:

В следующих разделах приведены примеры использования списков, разделенных запятыми, с массивами ячеек. Каждый из этих примеров также применим к структурам MATLAB.

Построение массивов

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

При указании списка элементов с C{:, 5}, MATLAB вставляет четыре отдельных элемента:

A = {'Hello',C{:,5},magic(4)}
A = 

    'Hello'    [34]    [36]    [38]    [40]    [4x4 double]

При указании C сама ячейка, MATLAB вставляет весь массив ячеек:

A = {'Hello',C,magic(4)}
A = 

    'Hello'    {4x6 cell}    [4x4 double]

Отображение массивов

Используйте список для отображения всей структуры или массива ячеек или их части:

A{:}
ans =

Hello


ans = 

    [2]    [10]    [18]    [26]    [34]    [42]
    [4]    [12]    [20]    [28]    [36]    [44]
    [6]    [14]    [22]    [30]    [38]    [46]
    [8]    [16]    [24]    [32]    [40]    [48]


ans =

    16     2     3    13
     5    11    10     8
     9     7     6    12
     4    14    15     1

Связь

Если поместить список, разделенный запятыми, в квадратные скобки, указанные элементы извлекаются из списка и объединяются:

A = [C{:,5:6}]
A =

    34    36    38    40    42    44    46    48

Аргументы вызова функции

При записи кода для вызова функции вводимые аргументы вводятся в виде списка с каждым аргументом, разделенным запятой. Если эти аргументы хранятся в структуре или массиве ячеек, можно сгенерировать все или часть списка аргументов из структуры или массива ячеек. Это может быть особенно полезно при передаче переменного числа аргументов.

В этом примере несколько аргументов значения атрибута передаются в plot функция:

X = -pi:pi/10:pi;
Y = tan(sin(X)) - sin(tan(X));
C = cell(2,3);
C{1,1} = 'LineWidth';
C{2,1} = 2;
C{1,2} = 'MarkerEdgeColor';
C{2,2} = 'k';
C{1,3} = 'MarkerFaceColor';
C{2,3} = 'g';
figure
plot(X,Y,'--rs',C{:})

Возвращаемые функции значения

Функции MATLAB также могут возвращать вызывающему абоненту более одного значения. Эти значения возвращаются в списке с каждым значением, разделенным запятой. Вместо перечисления каждого возвращаемого значения можно использовать список, разделенный запятыми, со структурой или массивом ячеек. Это становится более полезным для тех функций, которые имеют переменные числа возвращаемых значений.

Этот пример возвращает массиву ячеек три значения:

C = cell(1,3);
[C{:}] = fileparts('work/mytests/strArrays.mat')
C = 

    'work/mytests'    'strArrays'    '.mat'

Пример быстрого преобразования Фурье

fftshift функция изменяет местами левую и правую половины каждого измерения массива. Для простого вектора, такого как [0 2 4 6 8 10] результат будет [6 8 10 0 2 4]. Для многомерного массива: fftshift выполняет этот своп вдоль каждого измерения.

fftshift использует векторы индексов для выполнения свопа. Для вектора, показанного выше, индекс [1 2 3 4 5 6] переупорядочен для формирования нового индекса [4 5 6 1 2 3]. Затем функция использует этот вектор индекса для изменения положения элементов. Для многомерного массива: fftshift должен создать вектор индекса для каждого измерения. Список, разделенный запятыми, значительно упрощает эту задачу.

Вот fftshift функция:

function y = fftshift(x)
    numDims = ndims(x);
    idx = cell(1,numDims);
    for k = 1:numDims
        m = size(x,k);
        p = ceil(m/2);
        idx{k} = [p+1:m 1:p];
    end
    y = x(idx{:});
end

Функция сохраняет векторы индекса в массиве ячеек idx. Построить этот массив ячеек относительно просто. Для каждого из N , определите размер этого размера и найдите целочисленный индекс, ближайший к средней точке. Затем создайте вектор, который поменяет местами две половины этого размера.

Используя массив ячеек для хранения векторов индекса и разделенный запятыми список для операции индексирования, fftshift сдвигает массивы любого размера, используя только одну операцию: y = x(idx{:}). Если бы вы использовали явное индексирование, вам бы пришлось написать одно if оператор для каждого измерения, которое должна обрабатывать функция:

    if ndims(x) == 1
        y = x(index1);
    else if ndims(x) == 2
        y = x(index1,index2);
        end
    end

Другим способом справиться с этим без списка, разделенного запятыми, будет циклический переход по каждому измерению, преобразование одного измерения за раз и перемещение данных каждый раз. При использовании списка, разделенного запятыми, данные перемещаются только один раз. Список, разделенный запятыми, позволяет очень легко обобщить операцию подстановки на произвольное число измерений.