MATLAB Answers

Use find to filter for results specified by user

1 ビュー (過去 30 日間)
Petros Katsoulis
Petros Katsoulis 2019 年 11 月 8 日
コメント済み: Petros Katsoulis 2019 年 11 月 14 日
I have a table with some data:
clothes = table;
clothes.Type = ["Suit";"Shirt";"Dress"];
clothes.Colour = ["Blue";"Red";"White"];
clothes.Price = [300;50;400];
I want to write a filter that allows a user to define what they are interested in in each category and return the result. A simple way to do this would be:
% User defined input
filters = struct;
filters.Type = "Shirt";
filters.Colour = "Red";
filters.Price = 50;
% Generate result
f = find(strcmp(clothes.Type,filters.Type) ...
& strcmp(clothes.Colour,filters.Colour) ...
& clothes.Price == filters.Price);
output = clothes(f,:);
Suppose the user doesn't want to filter for the price and wants to see all results relevant to Red Shirts. Is there a way to write the code in such a way that when the user doesn't set any value to the filter (e.g. filters.Price = []), the find function will return all table entries with Red Shirts irrespectively of price? I thought about checking if it is empty then set the filter to contain all unique values of the relevant column of the table, but the real dataset is quite large and it's not very efficient.
Thank you.

  0 件のコメント

Sign in to comment.

採用された回答

Jan Studnicka
Jan Studnicka 2019 年 11 月 8 日
Hi,
strcmp is slower then == and you can use == with strings. You can also save space and get better performance by using categorical arrays instead of strings when it makes sence.
Check documentation for more information about categorical arrays.

  3 件のコメント

Petros Katsoulis
Petros Katsoulis 2019 年 11 月 9 日
Thank you! The actual code is more complex than this - I made it simple here to illustrate what I would like to do ideally, i.e. taking into account the possibility the user doesn't input a value to the filter.
Jan Studnicka
Jan Studnicka 2019 年 11 月 11 日
I would do it this way:
function st = tfilters(t,userinput)
vn = t.Properties.VariableNames;
idxV = ones(size(t));
for i = 1:length(vn)
if ismember(vn{i},fields(userinput))
if isempty(userinput.(vn{i})) == false
idxV(:,i) = t{:,vn{i}} == userinput.(vn{i});
end
end
end
idx = all(idxV,2);
st = t(idx,:);
However, instead of structures I would suggest using OOP.
Petros Katsoulis
Petros Katsoulis 2019 年 11 月 14 日
Thank you! This works.

Sign in to comment.

その他の回答 (0 件)

タグ


Translated by