多个命令合二为一,Matlab

时间:2016-03-31 14:17:04

标签: matlab function-calls function-call function-composition

有时需要在一个命令中进行多次调用。一个简单的例子可能是strrep。假设您要用括号替换所有括号,所有逗号用点替换,然后删除所有双引号。然后可能需要以下伪代码:

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

有没有办法实现这个目标?你当然可以选择:

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

或者将字符串保存在单元格数组中并在for循环中使用它,但这两种解决方案都非常难看。

最理想的答案是对所有以类似方式工作的函数都是通用的。

3 个答案:

答案 0 :(得分:5)

要直接回答你的问题,实际上没有一致的方法可以做到这一点,不。这真的取决于功能。如果您搜索文档,您通常会找到一种方法来执行此操作。至少使用字符串,您通常可以通过单元格数组代替字符串来对多个字符串执行操作,在这种情况下,对相同的字符串执行多个操作。

此特定示例的解决方案

您可以轻松使用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, {'[]', '.', ''});

答案 1 :(得分:1)

假设您希望函数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]

答案 2 :(得分:0)

正如@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 )
相关问题