Анонімні функції, які викликають функції з декількома формами виводу

Я намагаюся визначити анонімну функцію, яка викликає версію функції, яка повертає кілька виходів.

Наприклад, функція find має дві можливі форми виводу:

[row,col] = find(X);

і

[ind] = find(X);

Скажімо, я хотів би вибрати першу форму всередині анонімної функції.

I have tried 1)

get_columns = @(x) x(2);

і 2)

get_columns = @(x,y) y;

Але коли я називаю:

get_columns(find(x))

The first version of get_columns thinks I am calling find as [ind] = find(X) і not as [row,col] = find(X);, while the second one complains with "Not enough input arguments".

Чи можна запускати певну форму виведення функції всередині анонімної функції ?

8
Можна створити допоміжну функцію, яка запитує обидва виходи. Див. Також stackoverflow.com/questions/3096281/& hellip;
додано Автор Jonas, джерело

2 Відповіді

Прямо, ні. На жаль, існує ряд функцій, які недоступні через анонімні функції, і доступ до декількох аргументів виводу є одним з них. (Інший, який я часто знаходжу, полягає в тому, що ви не можете визначити оператор if в межах анонімної функції.

Тим не менш, досить проста допоміжна функція може зробити це можливим.

function varargout = get_outputs(fn, ixsOutputs)
output_cell = cell(1,max(ixsOutputs));
[output_cell{:}] = (fn());
varargout = output_cell(ixsOutputs);

Ця функція приймає ручку функції плюс масив вихідних індексів і повертає індексовані виходи.

Якщо ви створили цей файл (сподіваюся, краще прокоментував) і поклав його на свій шлях, то ви зможете отримати доступ до другого виходу функції find , визначивши наступну функцію

find_2nd = @(x)get_outputs(@()find(x),2)

А тепер ви можете знайти знайдені індекси масиву, які дорівнюють 1 as

>> find_2nd([4 3 2 1]==1)
ans =
    4

А тепер ви повинні мати доступ до альтернативних вихідних аргументів at-will з анонімних функцій.

8
додано

Ця функція get_outputs вище може бути дуже корисною для коротких анонімних функцій. Дуже хороша.

Крім того, щодо коментаря, що "if" не може бути використано в MATLAB, це лише частково вірно. Ідентична поведінка може бути легко реалізована анонімно. Наприклад, ось анонімний, якщо:

anonymous_if = @(varargin) varargin{2*find([varargin{1:2:end}], 1, 'first')}();

Використовувати:

out = anonymous_if(condition1, action1, condition2, action2, ...);

Виконана дія, що відповідає першому справжньому умові. Наприклад, це виводить "привіт".

anonymous_if(false, @() disp('hi'), ... % if false, print 'hi'
             true,  @() disp('hello'))  % else if true, print 'hello'

Звичайно, це трохи складніше на перший погляд, але я тримаю щось подібне на моєму шляху, так що я можу використовувати "якщо" в анонімній функції. У такий спосіб можна побудувати набагато складніші анонімні функції.

3
додано