Is there a Matlab conditional IF operator that can be placed INLINE like VBA's IIF

后端 未结 10 1191
滥情空心
滥情空心 2020-12-01 11:06

In VBA I can do the following:

A = B + IIF(C>0, C, 0)

so that if C>0 I get A=B+C and C<=0 I get A=B

相关标签:
10条回答
  • 2020-12-01 11:07

    How about simply using the fact that MATLAB automatically converts variable types when required by the operation? E.g., logical to double.

    If your variables are scalar double, your code, I believe, can be replaced by

    a = b + (c > 0) * c;
    

    In this case, the operator (c > 0) values 1 (logical type) whenever c > 0 and values to 0 otherwise.

    0 讨论(0)
  • 2020-12-01 11:11

    There is no built-in solution for this, but you can write an IIF yourself.

    function result=iif(cond, t, f)
    %IIF - Conditional function that returns T or F, depending of condition COND
    %
    %  Detailed 
    %     Conditional matrix or scalar double function that returns a matrix
    %     of same size than COND, with T or F depending of COND boolean evaluation
    %     if T or/and F has the same dimensions than COND, it uses the corresponding 
    %     element in the assignment
    %     if COND is scalar, returns T or F in according with COND evaluation, 
    %     even if T or F is matrices like char array.
    %
    %  Syntax
    %    Result = iif(COND, T, F)
    %           COND - Matrix or scalar condition
    %           T  - expression if COND is true
    %           F  - expression if COND is false
    %           Result - Matrix or scalar of same dimensions than COND, containing
    %                    T if COND element is true or F if COND element is false.
    %
    if isscalar(cond) 
       if cond 
           result = t;
       else
           result = f;
       end
    else
      result = (cond).*t + (~cond).*f;
    end  
    end
    
    0 讨论(0)
  • 2020-12-01 11:13

    Others have said already that there is no ternary ?: operator in Matlab. As a solution I suggest this function, which takes three functions instead of values. Therefore the amount of unnecessary calculations is minimized and you can check conditions before starting calculations, e.g. if a value is really numeric, or finite, or nonzero:

    function [ out ] = iif( condition, thenF, elseF, in, out)
    %iif Implements the ternary ?: operator
    %   out = iif (@condition, @thenF, @elseF, in[, out])
    %
    %   The result is equivalent to:
    %   condition(x) ? thenF(x) : elseF(x)
    %
    %   The optional argument out serves as a template, if the output type is
    %   different from the input type, e.g. for mapping arrays to cells and
    %   vice versa.
    %
    % This code is in the public domain.
    
    mask = condition(in);
    if nargin <= 4
      out = in;
    end
    
    if sum(mask)
      out(mask)  = thenF(in(mask));
    end
    if sum(~mask)
      out(~mask) = elseF(in(~mask));
    end
    
    end
    

    Use it like this:

    f = @(y)(iif(@(x)(x > 3), @(x)(x.^2), @(x)(x/2), y))
    f(linspace(0,6,10))
    
    0 讨论(0)
  • 2020-12-01 11:16

    Inspired by Jonas' answer the function below also works for mixed type input and chars, for which his function isn't stable.

    function out = iif(cond, a, b)
    %IIF implements a ternary operator
    
        % Use cell output for either char or mixed type input
        if ischar(a) || ischar(b) || ~strcmp(class(a), class(b))
            out = cell(size(cond));
            [out{cond}] = deal(a);
            [out{~cond}] = deal(b);
        else
            % Use array output and logical indexing
            out = repmat(b, size(cond));
            out(cond) = a;
        end
    end
    

    Edit: weeded out the extra conditional options in the cell branch, which were apparently remnants of a previous mistake, this is probably faster, and definitely cleaner.

    0 讨论(0)
  • 2020-12-01 11:19

    There is now a tern function on the MathWorks file exchange: http://www.mathworks.com/matlabcentral/fileexchange/39735-functional-programming-constructs/content/tern.m

    The code is reproduced here:

    function varargout = tern(condition, true_action, false_action)
    
    % out = tern(condition, true_action, false_action)
    % 
    % Ternary operator. If the first input is true, it returns the second
    % input. Otherwise, it returns the third input. This is useful for writing
    % compact functions and especially anonymous functions. Note that, like
    % many other languages, if the condition is true, not only is the false
    % condition not returned, it isn't even executed. Likewise, if the
    % condition is false, the true action is never executed. The second and
    % third arguments can therefore be function handles or values.
    %
    % Example:
    %
    % >> tern(rand < 0.5, @() fprintf('hi\n'), pi)
    % ans =
    %     3.1416
    % >> tern(rand < 0.5, @() fprintf('hi\n'), pi)
    % hi
    %
    % It works with multiple outputs as well.
    %
    % >> [min_or_max, index] = tern(rand < 0.5, ...
    %                               @() min([4 3 5]), ...
    %                               @() max([4 3 5]))
    % min_or_max =
    %      5
    % index =
    %      3
    %
    % Tucker McClure
    % Copyright 2013 The MathWorks, Inc.
    
        if condition() % Works for either a value or function handle.
            [varargout{1:nargout}] = true_action();
        else
            [varargout{1:nargout}] = false_action();
        end
    
    end
    
    0 讨论(0)
  • 2020-12-01 11:21

    Using:

    eval('input;', 'input = 1;');

    is very helpful where 'input' might not exist in the first place.

    0 讨论(0)
提交回复
热议问题