简体   繁体   中英

Is there an Octave equivalent of Matlab's `contains` function?

Is there an equivalent of MATLAB's contains function in Octave? Or, is there a simpler solution than writing my own function in Octave to replicate this functionality? I am in the process of switching to Octave from MATLAB and I use contains throughout my MATLAB scripts.

Let's stick to the example from the documentation on contains : In Octave, there are no (double-quoted) strings as introduced in MATLAB R2017a. So, we need to switch to plain, old (single-quoted) char arrays. In the see also section , we get a link to strfind . We'll use this function, which is also implemented in Octave to create an anonymous function mimicking the behaviour of contains . Also, we will need cellfun , which is available in Octave, too. Please see the following code snippet:

% Example adapted from https://www.mathworks.com/help/matlab/ref/contains.html

% Names; char arrays ("strings") in cell array
str = {'Mary Ann Jones', 'Paul Jay Burns', 'John Paul Smith'}

% Search pattern; char array ("string")
pattern = 'Paul';

% Anonymous function mimicking contains
contains = @(str, pattern) ~cellfun('isempty', strfind(str, pattern));
% contains = @(str, pattern) ~cellfun(@isempty, strfind(str, pattern));

TF = contains(str, pattern)

The output is as follows:

str =
{
  [1,1] = Mary Ann Jones
  [1,2] = Paul Jay Burns
  [1,3] = John Paul Smith
}

TF =
  0  1  1

That should resemble the output of MATLAB's contains .

So, in the end - yes, you need to replicate the functionality by yourself, since strfind is no exact replacement.

Hope that helps!


EDIT: Use 'isempty' instead of @isempty in the cellfun call to get a faster in-built implementation (see carandraug's comment below).

I'm not too familiar with MuPad functions, but it looks like this is reinventing the ismember function (which exists in both Matlab and Octave).

Eg

ismember( {'jim', 'stan'}, {'greta', 'george', 'jim', 'jenny'} )
% ans = 1  0

ie 'jim' is a member of { 'greta' , 'george' , 'jim' , 'jenny' }, whereas 'stan' is not.

Furthermore, ismember also supports finding the index of the matched element:

[BoolVal, Idx] = ismember( {'jim', 'stan'}, {'greta', 'george', 'jim', 'jenny'} )
% BoolVal = 1  0
% Idx     = 3  0

Personally I use my own implementation, which returns 1 if a string str contains entire substring sub :

function res = containsStr(str, sub)
res = 0;

strCharsCount = length(str);
subCharsCount = length(sub);

startCharSub = sub(1);

% loop over character of main straing
for ic = 1:strCharsCount
    currentChar = str(ic);
    % if a substring starts from current character
    if (currentChar == startCharSub)
        %fprintf('Match! %s = %s\n', currentChar, startCharSub);
        
        matchedCharsCount = 1;
        % loop over characters of substring
        for ics = 2:subCharsCount
            nextCharIndex = ic + (ics - 1);
            % if there's enough chars in the main string
            if (nextCharIndex <= strCharsCount)
                nextChar = str(nextCharIndex);
                nextCharSub = sub(ics);
                if (nextChar == nextCharSub)
                    matchedCharsCount = matchedCharsCount + 1;      
                end
            end
        end
        
        %fprintf('Matched chars = %d / %d\n', matchedCharsCount, subCharsCount);
        
        % the substring is inside the main one
        if (matchedCharsCount == subCharsCount)
            res = 1;  
        end
    end
end

end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM