Find a vector in a structure
조회 수: 3 (최근 30일)
이전 댓글 표시
Hello! I've this structure:
>> vortex(:).points
ans =
1 2 3
4 5 6
7 8 9
ans =
9 9 9
8 8 8
I want to find the [8 8 8] vector in any of the vortex array and the position in both the vortex and the points array. Something like:
find([8 8 8], vortex) --> vortex(2).points(2, :)
find([7 8 9], vortex) --> vortex(1).points(3, :)
How should I do?
댓글 수: 0
채택된 답변
Andrei Bobrov
2012년 1월 17일
variant
pall = cat(1,vortex(:).points);
a = find(ismember(pall,[7 8 9],'rows'));
b = cumsum([0 arrayfun(@(x) size(x.points,1), vortex)]);
[i1 i1] = histc(a,b+100*eps);
d = a - b;
j1 = d(find(d>0,1,'last'));
out = vortex(i1).points(j1,:)
댓글 수: 0
추가 답변 (1개)
David Young
2012년 1월 16일
One method:
% Test data
vortex(1).points = [1 2 3; 4 5 6; 7 8 9];
vortex(2).points = [9 9 9; 8 8 8];
searchv = [9 9 9];
% Analyse structure to find how many rows are in each points matrix.
% No need to repeat this line if searchv changes, only if vortex does.
rowsums = cumsum([0 arrayfun(@(x) size(x.points, 1), vortex)]);
% Assemble all the points arrays into one big array, and look for the first
% row that is the same as the search vector.
row = find(~any(bsxfun(@minus, vertcat(vortex(:).points), searchv), 2), 1);
% check that a matching row has been found, to avoid an obscure error later
if isempty(row)
error('Vector not found');
end
% Convert the overall row number into the structure and array indices,
% so that vortex(struct_index).points(points_index,:) is equal
% to searchv.
struct_index = find(row <= rowsums, 1) - 1
points_index = row - rowsums(struct_index)
EDIT Revised code below, inspired by andrei bobrov's answer, making use of ismember and separating out building the large matrix.
% Analyse structure to find how many rows are in each points matrix, and
% concatenate the points matrices into one big matrix.
% No need to repeat these two lines if searchv changes, only if vortex does.
rowsums = cumsum([0 arrayfun(@(x) size(x.points, 1), vortex)]);
pall = vertcat(vortex(:).points);
% Look for the last row that is the same as the search vector.
[~, row] = ismember(searchv, pall, 'rows');
% check that a matching row has been found, to avoid an obscure error later
if ~row
error('Vector not found');
end
% Convert the overall row number into the structure and array indices,
% so that vortex(struct_index).points(points_index,:) is equal
% to searchv.
struct_index = find(row <= rowsums, 1) - 1
points_index = row - rowsums(struct_index)
댓글 수: 2
David Young
2012년 1월 17일
See if Andrei Bobrov's variant is faster. In particular I think his use of ismember is better than my method of subtracting and finding a line of zeros - it's certainly more elegant.
In addition, Andrei builds the big concatenated matrix ('pall') separately from searching it, and this is very sensible, because you should not rebuild it before searching for another vector.
It might be worth having a look at the structure of your whole program, to see if there is some way of avoiding building the structures in the first place, or of indexing them when they are being built.
참고 항목
카테고리
Help Center 및 File Exchange에서 Numeric Types에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!