Clear Filters
Clear Filters

How do I modify/add data to a struct along specific field string values?

33 views (last 30 days)
I've got a structure array full of data that I'm working with, with several entries that have fields for an identifying string and numerical data. The values of the string fields have patterns to them; something along the lines of
STR.type = "green fruits"; STR.numbers = rand(10,1);
STR(2).type = "red fruits"; STR(2).numbers = rand(10,1);
STR(3).type = "green veggies"; STR(3).numbers = rand(10,1);
STR(4).type = "other fruits"; STR(4).numbers = rand(10,1);
STR(5).type = "other veggies"; STR(5).numbers = rand(10,1);
(Not what I'm actually working with, but I don't want to just have the work done for me.)
I need to identify the entries for one category by a common substring that they share (for example contains([STR.type],"fruits")), then I need to create a new field for entries that match the substring, then create a vector in each of those entries that contains the difference between its corresponding 'numbers' data vector and a specific 'numbers' vector (for example, calculate every vector of the "fruits" type minus the vector in the "other fruits" entry, then assign that to the new field).
I've managed to do this before with small data sets by rearranging the entry with the common subtraction vector to be the first entry, then simply using a for loop with numerical indexing to call and modify data as needed. But now I'm starting to deal with structs that have more entries and multiple substrings to be considered, so I figured I need a more flexible method now.
I've already figured out that I can use something like this to identify the entries I need to modify:
STR(contains([STR.type],"fruits")).numbers
. . . and I can call the vector to be subtracted like so:
STR([STR.type] == "other fruits").numbers
. . . and I've got this anonymous function to apply:
func = @(x) STR(x).numbers - STR([STR.type] == "other fruits").numbers
But when I try to use arrayfun to do the subtraction and assignment as follows, I get the error "Unable to use a value of type struct as an index":
STR.newnumbers = arrayfun(func, STR(contains([STR.type], "fruits")))
Am I just missing a small detail to make this work, or is my approach flawed from the start? I'd like to find a way to pull this off with something like 'arrayfun' or 'deal' without relying on any sort of loop that would assume the entries are conveniently ordered.

Accepted Answer

Bruno Luong
Bruno Luong on 19 Aug 2022
Edited: Bruno Luong on 19 Aug 2022
Try this:
func = @(x) STR(x).numbers - STR([STR.type] == "other fruits").numbers
isfruit = contains([STR.type], "fruits");
newnumber = arrayfun(func, find(isfruit), 'unif', false);
[STR(isfruit).newnumber] = deal(newnumber{:});
  3 Comments

Sign in to comment.

More Answers (0)

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Products


Release

R2022a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!