Несколько команд в одной, Matlab

Иногда желательно сделать несколько вызовов в одной команде. Простым примером может быть strrep. Предположим, вы хотите заменить все круглые скобки скобками, все запятые точками, а затем удалить все двойные кавычки. Тогда может потребоваться следующий псевдокод:

strrep(myString, '()', '[]', ',', '.', '"', '')

Есть ли способ сделать это? Конечно, вы могли бы пойти с:

strrep(strrep(strrep(myString, '()', '[]'), ',', '.'), '"', '')

Или сохраните строки в массиве ячеек и используйте это в цикле for, но оба решения невероятно уродливы.

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


person jkazan    schedule 31.03.2016    source источник
comment
Осмелюсь сказать, что нет общего решения ни для одной функции, кроме зацикливания. Для конкретного случая см. ответ Suevers.   -  person thewaywewalk    schedule 31.03.2016
comment
В чем разница между скобками и скобками? Они одинаковые, насколько я знаю.   -  person kkuilla    schedule 31.03.2016
comment
@kkuilla на английском языке да, но в программе принято называть () круглые скобки, [] скобки и {} фигурные скобки. Это просто условность, а не правило и уж точно не правило английского языка.   -  person Dan    schedule 31.03.2016
comment
В моем соглашении о кодировании это называется скобками (), квадратными скобками []. Никто из тех, кого я знаю, не называет их скобками. Может дело в американцах...   -  person kkuilla    schedule 31.03.2016
comment
Я также слышал о фигурных скобках - {}. А также фигурные скобки - (), квадратные скобки - [] и фигурные скобки - {}... В большинстве случаев я встречаю соглашение, о котором упоминал @Dan...   -  person Crowley    schedule 31.03.2016
comment
@kkuilla это интернет-вещь: google.co.za/ конечно, вы можете называть их как хотите, я бы использовал ту же терминологию, что и вы в разговорной речи, но соглашение, которое я разместил, является наиболее подписанным, и если вы хотите чтобы люди в Интернете знали, что вы имеете в виду, довольно недвусмысленно, тогда я боюсь, что это условность. (кстати, эта страница утверждает, что она американская, но нет Справка)   -  person Dan    schedule 31.03.2016


Ответы (3)


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

Решение для этого конкретного примера

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

regexprep('abc', {'a', 'b', 'c'}, {'1', '2', '3'});

%// '123'

Для вашего конкретного примера вы должны сделать что-то вроде:

regexprep(myString, {'\(\)', ',', '"'}, {'[]', '.', ''})

И в качестве примера:

myString = 'This, is a () "string"';
regexprep(myString, {'\(\)', ',', '"'}, {'[]', '.', ''})

%// 'This. is a [] string'

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

expressions = regexptranslate('escape', {'()', ',', '"'});
regexprep(myString, expressions, {'[]', '.', ''});
person Suever    schedule 31.03.2016
comment
У вас есть идея, почему regexprep(myString, {'\(\)', '.', '"'}, {'[]', ',', ''}) заменяет каждый символ запятой? regexprep(myString, {'\(\)', '\.', '"'}, {'[]', ',', ''}) будет работать как положено. - person Crowley; 01.04.2016
comment
@Crowley в регулярном выражении точка соответствует любому символу. Вам нужно будет экранировать его (\.) или использовать regexptranslate, как в моем последнем примере. - person Suever; 01.04.2016
comment
Да, это имеет смысл :) - person Crowley; 01.04.2016

Допустим, вы хотите, чтобы функция foo работала так:

foo(Variable,Parameter1,Value1);
foo(Variable,Parameter1_1,Value1,Parameter2,Value2,...);

затем с помощью рекурсии:

function[Variable]=FooBar(Variable,varargin)
N=nargin-1;                  %\\ Count the input parameters
if N>=2
  Parameter=varargin{1};      
  Value=varargin{2};
  % Process the first Parameter-value pair
  Variable=FooBar(Variable,varargin{3:N}); %\\ Cut first Parameter-Value pair off and pass the rest to foo again 

end

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

В этом конкретном примере пары выполняются как стек LIFO, а последний непарный Parameter игнорируется. Вы также можете добавить некоторые условия для реализации foo(IN,Parameter1,Value1,Modifier,Parameter2,Value2,...) и многих других свойств...

Для вашего пертикулярного примера:

function[MyString]=FooBar(MyString,varargin)
N=nargin-1;                  %\\ Count the input parameters
if N>=2
  Parameter=varargin{1};
  Value=varargin{2};
  MyString=regexprep(MyString,Parameter,Value)
  MyString=FooBar(MyString,varargin{3:N});%\\ Cut first Parameter-Value pair off and pass the rest to foo again 

end

Примеры:

>> myString='This, is a () "string"';
FooBar(myString,'()','[]','"','',',','.')
ans = This. is a [] string

>> myString='This, is a  ("string")';
FooBar(myString,'()','[]','"','',',','.')
ans = This. is a  (string)

>> myString='This, is a  ("string")';
FooBar(myString,'(','[',')',']','"','',',','.')
ans = This. is a  [string]
person Crowley    schedule 31.03.2016

Как уже сказал @Suever, ваш пример может быть решен с помощью regexprep, а @thewaywewalk намекнул, что не существует «общего» решения для всех вызовов функций.

Примечание. Я не пропагандирую это как хороший способ кодирования ->, но это причудливый вопрос, и поэтому здесь есть подходящее причудливое решение....

Есть много причин, по которым вы не должны этого делать, а именно кошмар для отладки, но теоретически вы можете сделать это с помощью "интеллектуальной" функции самовызова...

% Create your own function which takes the following inputs:
%     fHandle  - function handle to the function of choice
%     property - your starting variable
%     varargin - a cell array (or single var) of variables to 
%                pass into the fHandle on each call
%  see examples below...
function output = multipleCalls ( fHandle, property, varargin )
  % call your primary function using feval and your inputs
  %   with the 1st group of inputs from the 1st varargin
  if iscell ( varargin{1} )
    output = feval ( fHandle, property, varargin{1}{:} );
  else
    output = feval ( fHandle, property, varargin{1} );
  end
  % remove the varargin variable which has just been used.
  varargin(1) = [];
  % are they aremore multiple call?
  if ~isempty ( varargin )
    % if so self call to apply the subsequent calls.
    output = multipleCalls ( fHandle, output, varargin{:} );
  end
end


% modifying your example to use this method:
multipleCalls( @strrep, 'This, is a () "string"', { '()', '[]' }, { ',', '.' }, { '"', '' } )
% Its probably a longer command and is it any clearer -> probably not...

% Here is another example:
% Create a silly anonymous function
sillyFunction = @(a,b) a + b

% Then you can use it in the same way:
% Where 0 is what you start with and then
%  each time you want to add 1, then 2, then 3 and finally 4
multipleCalls ( sillyFunction, 0, 1, 2, 3, 4 )
person matlabgui    schedule 31.03.2016