【问题标题】:Multiple commands in one, Matlab多个命令合二为一,Matlab
【发布时间】:2016-03-31 14:17:03
【问题描述】:

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

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

有没有办法做到这一点?你当然可以选择:

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

或者将字符串保存在一个元胞数组中并在 for 循环中使用它,但这两种解决方案都非常丑陋。

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

【问题讨论】:

  • 我敢说任何函数都没有通用的解决方案,除了循环。具体情况见 Suevers 回答。
  • 圆括号和方括号有什么区别?据我所知,它们是一样的。
  • @kkuilla 在英语中是的,但在程序约定中是调用() 括号、[] 括号和{} 括号。这只是一个约定,不是规则,当然也不是英语规则
  • 在我的编码约定中称为方括号(),方括号[]。我认识的没有人称它们为括号。也许这是美国的东西......
  • @kkuilla 这是一个互联网事物:google.co.za/… 当然,您可以随意称呼他们,我会使用与您口语相同的术语,但我发布的约定是最受订阅的,并且如果您希望互联网上的人们相当明确地知道您的意思,那么恐怕这是使用的惯例。 (顺便说一句 this page 声称它是美国的,但没有参考)

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


【解决方案1】:

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

此特定示例的解决方案

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

【讨论】:

  • 你知道为什么regexprep(myString, {'\(\)', '.', '"'}, {'[]', ',', ''}) 用逗号改变每个字符吗? regexprep(myString, {'\(\)', '\.', '"'}, {'[]', ',', ''}) 将按预期工作。
  • @Crowley 在正则表达式中,点匹配 any 字符。您需要将其转义 (\.) 或使用 regexptranslate,如上一个示例所示。
  • 是的,这是有道理的:)
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    正如@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 )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多