我有一个包含文件名的单元格数组。我想检查主题文件夹中是否存在所有这些文件,如果任何一个文件不存在,我希望继续发送到最顶层的for循环(参见模拟代码)。有没有办法在一个或两个衬里中执行此操作,而不是1)使用for循环和双if语句,或2)构建for循环over()的函数。
subjects = {'/data/subject01','/data/subject02','/data/subject03'};
files = {'a.txt','b.txt','c.txt'};
for ii = 1:numel(subjects)
for jj = 1:numel(files)
fileExists = exist([subject{ii} '/' file{jj}],'file')
if ~fileExists
continue
end
end
if ~fileExists
continue
end
% Some code to execute if all files exist.
end
答案 0 :(得分:2)
*fun
函数只是内部循环,通常比显式循环慢。它们也经常不必要地混淆代码的意图和行为。
您可以ismember
与all
和dir
一起使用,以使方法更清晰,并删除不必要的循环:
subjects = {'./data/subject01','./data/subject02'};
files = {'a.txt','b.txt','c.txt'};
for ii = 1:numel(subjects)
filelist = dir(fullfile(subjects{ii}, '*.txt'));
foundfilenames = {filelist(:).name};
if all(ismember(files, foundfilenames))
fprintf('All %u files are here: %s\n', numel(files), subjects{ii})
else
fprintf('All %u files are not here: %s\n', numel(files), subjects{ii})
end
end
使用我的文件夹结构:
/data
/subject01
a.txt
b.txt
/subject02
a.txt
b.txt
c.txt
我按预期看到以下内容:
All 3 files are not here: ./data/subject01
All 3 files are here: ./data/subject02
答案 1 :(得分:1)
您可以通过迭代两个数组的所有组合来删除循环:
subjects = {'/data/subject01','/data/subject02','/data/subject03'};
files = {'a.txt','b.txt','c.txt'};
a=numel(subjects);
b=numel(files);
k=a*b;
paths = arrayfun(@(ii)[subjects{mod(ii-1,a)+1} '/' files{ceil(ii/b)}],1:k,'uniformoutput',0);
checkExist = cellfun(@exist, paths, repmat({'file'},1,k));
if all(checkExist)
% Some code to execute if all files exist
end
答案 2 :(得分:0)
使用cellfun和字符串数组解决它。从技术上讲,仍有一个for循环,但它解析了双if语句。我会留下这个问题以获得更好的解决方案。
subjects = {'/data/subject01','/data/subject02','/data/subject03'};
files = string({'a.txt','b.txt','c.txt'});
for ii = 1:numel(subjects)
paths = subject{ii} + files;
checkExist = cellfun(@exist, cellstr(paths), repmat({'file'},size(paths))
if ~all(checkExist(:))
continue
end
% Some code to execute if all files exist.
end