How to keep ordering of found indices when using contains?
3 views (last 30 days)
Show older comments
Hi Everyone,
I have a cell array called "data" containing a field "data.labels". In addition to that I have the cell "lbls" containing label strings and I would like to find the indices of elements in data.labels that contain lbls.
Using
idx = find(contains(data.labes,lbls));
is doing the job but returns the indices sorted in ascending order. How can I keep the original ordering of the indices?
Thanks in advance and all best,
M.
0 Comments
Accepted Answer
dpb
on 24 Aug 2018
Edited: dpb
on 24 Aug 2018
It's not being sorted, it's returning the matches that are found globally just like you asked it to do, not by individual elements in the searching-for array. The contains operation is completed, then that result is passed to find. The locations in the label array are where they are; there's no way to know which of the elements it was that was the one found at any given location; that's not what you asked for.
If you want them returned individually, you'll have to do the search for the elements in lbls one at a time; don't think of any way to differentiate which match is which, otherwise.
Example (modified from cotains documentation):
str = ["Anne","Elizabeth","Marianne","Tracy"]; % sample data; struct is immaterial to problem
pattern = "anne"; % find one location
TF = find(contains(str,pattern,'IgnoreCase',true));
TF =
1 3
returns the two locations expected...nothing to see here, really.
pattern = ["anne";"liz"]; % now find more than one element
TF=find(contains(str,pattern,'IgnoreCase',true));
find(TF)
TF =
1 2 3
Again, it finds then all but the '2' is for 'Elizabeth'. Nothing was sorted, per se, just that as noted, the search is global.
str(end+1)=str(2); str(2)=[] % rearrange to put lizzie at the end...
str =
1×4 string array
"Anne" "Marianne" "Tracy" "Elizabeth"
TF = find(contains(str,pattern,'IgnoreCase',true))
TF =
1 2 4
To find individual locations that can keep track of who,
>> TF=arrayfun(@(pattern) find(contains(str,pattern,'IgnoreCase',true)),pattern,'uni',0)
TF =
2×1 cell array
{1×2 double}
{[ 4]}
>> TF{:}
ans =
1 2
ans =
4
3 Comments
dpb
on 24 Aug 2018
Edited: dpb
on 24 Aug 2018
find is operating on data.labels; the positions of the two elements is where they are in the array; find tells you where in that array; it has nothing to do with the order in some other array.
contains is simply the wrong tool for the recast question...
[liaA,libA]=ismember(labels,lblsA);
[liaB,libB]=ismember(labels,lblsB)
[liaA libA liaB libB]
ans =
0 0 0 0
1 2 1 1
0 0 0 0
1 1 1 2
0 0 0 0
find will still return [2 4] for both because that's where the entries are but the second return argument will tell where in the second array they're located in that order.
You have to recognize you're asking for the location with respect to the second array, not the first to have the other piece of information.
All in all, I'd think the first solution will probably work out more easily used but don't know the actual end application.
More Answers (0)
See Also
Categories
Find more on Shifting and Sorting Matrices in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!