检查向量是否在结构中

时间:2014-12-01 20:51:55

标签: matlab

如果我有结构,例如:

vars =
    var1: [3 1 3]
    var2: [2 2 8]
    var3: [2 3 4]
    var4: [1 4 5]

如何检查vec = [2 2 8]之类的内容是否在结构中的某个位置?或者,如果有一个数字,那么?

3 个答案:

答案 0 :(得分:2)

按字段名称搜索

您可以使用isfield按字段名称搜索:

isfield(vars,'vec')
如果true是结构vec的字段,

将返回vars

按字段值搜索

这有点复杂。您必须先从结构中获取所有字段,然后遍历它们并将它们与您感兴趣的数据进行比较。这是一个例子,它可能不是最有效或最优雅的一个,但它应该有效:

% Data
vars.var1 = [3 1 3];
vars.var2 = [2 2 8];
vars.var3 = [2 3 4];
vars.var4 = [1 4 5];
vec = [2 2 8];

% Get field names
names = fieldnames(vars); % I assume you do not know a priori what fields are in vars

% Go through the fields in the structure
idx = false(length(names),1);
disp_str = '';
for k=1:length(names)
    if isequal(vec,vars.(names{k}))
        idx(k) = true;
        if isempty(disp_str)
            disp_str = names{k};
        else
            disp_str = [disp_str ' and ' names{k}];
        end
    end
end

% Display the results
if max(idx)>0
    disp(['Match found in ' disp_str]);
else
    disp('No match found')
end

答案 1 :(得分:2)

使用structfun将函数(即等式检查)应用于标量结构的每个字段:

>> vars = struct('var1',[3 1 3],'var2',[2 2 8],'var3',[2 3 4],'var4',[1 4 5])
vars = 
    var1: [3 1 3]
    var2: [2 2 8]
    var3: [2 3 4]
    var4: [1 4 5]
>> testVec = [2 2 8];
>> b = structfun(@(f)isequal(f,testVec),vars)
b =
     0
     1
     0
     0

并根据您的目的更改功能。例如,ismemberintersectany(f==scalar)

答案 2 :(得分:1)

这个问题比看起来更有趣。

上述答案仅在vec的大小等于struct中向量的大小时才有效。问题的第二部分怎么样:"或者如果有一个数字,那么?"

尝试以下代码。它在结构的字段值中搜索向量(任何大小)的出现。

function [fields, ismember] = ipl_ismemberofstruct(struct, needle)

% Get needle string
needle_str = ipl_getmatstr(needle);

% Retrieve field names from struct
fields = fieldnames(struct);

% Prepare some variables
ismember = false(1, length(fields));
delimiters = ' ;';

% Loop through each field looking for needle
for i=1:length(fields)
    [fieldvalue_str] = ipl_getmatstr(struct.(fields{i}));
    [contains] = ipl_strcontains(fieldvalue_str, needle_str, delimiters);
    ismember(i) = contains;    
end
end

% ------------------------------------------------------------------------
function [contains] = ipl_strcontains(haystack, needle, delimiters)

contains = false; 

% Get occurrences of needle on haystack
idxs = strfind(haystack, needle);

% Verify each occurrence (just whole occurrences are taken into account)
for i=1:length(idxs)

    % The character before needle must be a delimiter (or the haystack begins with needle)
    before_idx = idxs(i) - 1; 
    before_clear = true;   
    if(before_idx > 0)
        k = strfind(delimiters, haystack(before_idx));
        if(isempty(k))
            before_clear = false;
        end
    end

    % The character after needle must be a delimiter (or the haystack ends with needle)
    after_idx = idxs(i) + length(needle);   
    after_clear = true;    
    if(after_idx <= length(haystack))
        k = strfind(delimiters, haystack(after_idx));
        if(isempty(k))
            after_clear = false;
        end
    end

    % If both variables are true, then needle is a 'whole' occurrence
    if(before_clear && after_clear)
        contains = true;
        return;
    end    
end
end

% ------------------------------------------------------------------------
function [matstr] = ipl_getmatstr(mat)

% Convert matrix to a string
matstr = mat2str(mat);

% Remove '[' and ']' characters, if they exists
if(numel(mat) > 1)
    matstr = matstr(2:(length(matstr)-1)); 
end
end

用例1:Vector [2 2 8]位于字段var2

vars = struct('var1',[3 1 3],'var2',[2 2 8],'var3',[2 3 4],'var4',[1 4 5])
vars = 

    var1: [3 1 3]
    var2: [2 2 8]
    var3: [2 3 4]
    var4: [1 4 5]

[fields, ismember] = ipl_ismemberofstruct(vars, [2 2 8])
fields = 

    'var1'
    'var2'
    'var3'
    'var4'


ismember =

     0     1     0     0

用例2:标量值[2]位于字段var2和var3

[fields, ismember] = ipl_ismemberofstruct(vars, 2)

fields = 

    'var1'
    'var2'
    'var3'
    'var4'


ismember =

     0     1     1     0