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).
contains
perform on large string arrays? Is there some smart algorithm working under the hood; or is there some optimization? From a naive point of view: There still must be n (sub)string findings. So, shouldn't any optimization with respect to that also be applicable to the strfind
approach? –
Maragaret @isempty
you pass the string with the function name isempty
it will use a faster implementation. –
Infielder 'isempty'
update. That is a nice trick to remember though. –
Johnsonian 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).
E.g.
ismember( {'jim', 'stan'}, {'greta', 'george', 'jim', 'jenny'} )
% ans = 1 0
i.e. '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
ismember
and contains
are not the same - hence the introduction of the contains
function. To extend your example, ismember( {'george', 'jim'}, 'eor' )
would return false for both input elements, but contains( {'george', 'jim'}, 'eor' )
returns true for 'george'
. –
Johnsonian 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
It is very simple to implement similar function in Octave. Follow code suing strfind does same job:
function tf = contains(str, substr)
% MATLAB equivalent of contain funciton in Octave
tf = ~isempty(strfind(str, substr));
end
© 2022 - 2024 — McMap. All rights reserved.
cellfun
is basically a loop, so this won't be very performant for large cell arrays. I imagine if the OP gave specific examples where this matters (if any) then there might be tailored solutions which are faster... – Johnsonian