Maroun
Maroun

Reputation: 95978

Matlab: Improving a tree traversal code

I have the structure that is demonstrated below:

database structure

I have a database folder which contains brands. Each brand consists of logo and query. I want to traverse on all the the files (file_1 to file_n) in all the database and perform some operations on them.

I wrote this code:

d = dir(database);
isub = [d(:).isdir];
brandsFolders = {d(isub).name}';
brandsFolders(ismember(brandsFolders,{'.','..'})) = [];
[numberOfBrands not_used]=size(brandsFolders); %holds the number of the brands
for i=1:numberOfBrands
    temp=strcat(database,  '\');
    currentBrand=strcat(temp, brandsFolders(i));
    d = dir(currentBrand{1,1});
    isub = [d(:).isdir];
    logoAndQuery = {d(isub).name}';
    logoAndQuery(ismember(logoAndQuery,{'.','..'})) = [];
    logo=strcat(currentBrand, '\', logoAndQuery(1));
    files=dir(logo{1,1});
    [numberOfFiles not_used]=size(files);
    for j=1:numberOfFiles
        if strcmp(files(j).name, '..')~=1 && strcmp(files(j).name, '.')~=1
            %operations on each files(j).name
        end
    end
end

The code works fine, it traverse on the desired files. However, the code is little bit ugly and confusing.

I was wondering if I can do it in another better way?

Upvotes: 1

Views: 653

Answers (1)

Gunther Struyf
Gunther Struyf

Reputation: 11168

Traversing through a set of directories goes pretty much as you are doing. However imo, there are some things you can do easier / I would do differently:

brandsFolders = dir(database);
brandsFolders( ~[brandsFolders.isdir] | strcmp({brandsFolders.name},'.') | strcmp({brandsFolders.name},'..')) = [];

for ii=1:numel(brandsFolders)
    logoAndQuery  = dir(fullfile(database,brandsFolders(ii).name));
    logoAndQuery( ~[logoAndQuery.isdir] | strcmp({logoAndQuery.name},'.') | strcmp({logoAndQuery.name},'..')) = [];

    logo = fullfile(databasecurrentBrand,brandsFolders(ii).name), logoAndQuery(1).name);
    files = dir(logo);
    files(strcmp({files.name},'.') | strcmp({files.name},'..'))=[];

    for jj=1:numel(files)
        %operations on each files(j).name
    end
end

(This of course only works if you're sure that logoAndQuery(1) will always be the 'logo' directory.)
or alternatively use a subfunction for the dir-querying:

function dirs = getDirs(strPath)
    dirs = dir(strPath);
    dirnames = {dirs.name};
    dirs ( ~[dirs.isdir] | strcmp(dirnames ,'.') | strcmp(dirnames ,'..')) = [];
end

which gives you already some shorter code and gives the following, in which I also assume there are no directories in the 'logo' directories:

brandsFolders = getDirs(database);

for ii=1:numel(brandsFolders)
    logoAndQuery  = getDirs(fullfile(database,brandsFolders(ii).name));
    logo = fullfile(databasecurrentBrand,brandsFolders(ii).name), logoAndQuery(1).name);
    files = dir(logo);
    files([files.isdir])=[];

    for jj=1:numel(files)
        %operations on each files(j).name
    end
end

Upvotes: 1

Related Questions