MATLAB Answers


How can I replace a loop with arrayfun - problems with strrep

Asked by SpeedyGonzales on 2 Apr 2015
Latest activity Commented on by SpeedyGonzales on 5 Apr 2015
Hi, I am trying to replicate the behavior of a loop using arrayfun, but running into problems. The loop that is working looks as follows:
for jj = 1:length(nodes1)
ix_ = find(nodes1{jj}=='_');
if length(ix_) >= 3
nodes1{jj}(ix_(3:end)) = '-';
The code is trying to achieve the following: It replaces all _ underscores after the 3rd underscore for all entries in nodes1.
I would like to figure out how to translate the loop to an arrayfun. This is the code that I have so far:
temp = arrayfun(@(x) find(nodes2{x}=='_'),1:lNode,'un',false);
temp2 = arrayfun(@(x) length(temp{x}),1:lNode);
temp3 = arrayfun(@(x) temp{x}(3:end),1:lNode,'un',false);
%temp4 = arrayfun(@(x) nodes2{x}(temp3{x})='-',1:lNode,'un',false);
temp4 = arrayfun(@(x) strrep(char(nodes2{x}(temp3{x})),'_','-'),1:lNode,'un',false);
The commented out %temp4 line gives me an error as I am not allowed to use an = sign in the arrayfun function. If I would run:
by itself, then this syntax would give me exactly what I want. My first thought was to then use strrep (last row of code), but even though the code executes, it doesn't replace the _ underscore in nodes2.
Any idea how I can get this to work with arrayfun? Why isn't my approach working? I would like to understand the underlying problem.


Sign in to comment.


1 Answer

Answer by Sven
on 2 Apr 2015
Edited by Sven
on 2 Apr 2015
 Accepted Answer

Hi Sven (congrats on the name),
Here's a pretty direct way to do what you're trying to do. It uses regexp once and cellfun once:
% Split each string into the first 3 underscores (tok1) and the rest (tok2)
toks = regexp(nodes1,'(.*?_){3}(.*)','tokens','once');
% Find which strings might actually need replacement
mask = ~cellfun(@isempty,toks);
% Perform replacement on tok2 only and merge it to unreplaced tok1
result = nodes1;
result(mask) = cellfun(@(tok)[tok{1} strrep(tok{2},'_','-')],toks(mask),'Un',0);
Did that help you out?
Thanks, Sven.

  1 Comment

Thanks Sven! Yes, this helped a lot, I just needed to change the regexp command slightly to only read in the portion that is defined by the first two underscores, then it worked perfectly!

Sign in to comment.