필터 지우기
필터 지우기

Adding structs within structs in a larger scale (without having to manually specify every field name)

조회 수: 2 (최근 30일)
So, I'm not a very good or efficient coder, but I want to structure alot of data and i think structs within structs will be the easiest for me to work with. Say I want to add som specific structs to other struct fields in a larger struct, but have too many field names to work with to write them all manually with the cell2struct function, how would I do that? Can copy the full code I have for now, I'm happy for any input. The bottom for-loop is basically the relevant part, I want to add the struct TimeFrame to every Coin-field, and later on add the relevant data for each coin given each timeframe. (For now I do not load all data I want to have in the end, I'm working with a smaller subset for the time being)
Thanks!
%%Fix stuff
url = 'https://api.binance.com/api/v1/klines';
symbols = load('BinanceSymbols.mat');
symbols = struct2cell(symbols);
symbols2 = {1:10};
for i = 1:10
symbols2{i} = symbols{1,1}{i,1};
end
symbols2 = symbols2';
%intervals = {'1h','2h','4h','6h','8h','10h','11h','12h','13h','14h','15h','16h','17h','18h','19h','20h','21h','22h','23h','1d'};
intervals = {'4h','12h','1d'};
intervals = intervals';
data = zeros(length(symbols2),length(intervals));
data = num2cell(data);
%%For-loop for data
for i = 1:length(symbols2)
symbol = symbols2{i};
for k = 1:length(intervals)
interval = intervals{k};
data{i,k} = webread(url,'symbol',symbol,'interval',interval,'limit',25);
end
end
%%Build struct
length1 = length(data{1,1});
t = struct;
Date4 = struct;
Close4 = struct;
Open4 = struct;
High4 = struct;
Low4 = struct;
Data4 = cell2struct({Date4;Close4;Open4;High4;Low4},{'Date','Close','Open','High','Low'},1);
Date12 = struct;
Close12 = struct;
Open12 = struct;
High12 = struct;
Low12 = struct;
Data12 = cell2struct({Date4;Close4;Open4;High4;Low4},{'Date','Close','Open','High','Low'},1);
Date1d = struct;
Close1d = struct;
Open1d = struct;
High1d = struct;
Low1d = struct;
Data1d = cell2struct({Date4;Close4;Open4;High4;Low4},{'Date','Close','Open','High','Low'},1);
TimeFrame = cell2struct(intervals,{'FourHours','TwelveHours','OneDay'},1);
Coin = cell2struct(symbols2,symbols2,1);
for i = 1:length(data)
Coin(i).TimeFrame = TimeFrame;
end
The struct then looks like this:
Coin =
struct with fields:
ETHBTC: 'ETHBTC'
LTCBTC: 'LTCBTC'
BNBBTC: 'BNBBTC'
NEOBTC: 'NEOBTC'
BCCBTC: 'BCCBTC'
GASBTC: 'GASBTC'
BTCUSDT: 'BTCUSDT'
ETHUSDT: 'ETHUSDT'
HSRBTC: 'HSRBTC'
MCOBTC: 'MCOBTC'
TimeFrame: [1×1 struct]
And i want the TimeFrame to be inside every coin as another struct and not as another field under the coin!
Thanks again for any input.
Edit: Added binancesymbols.mat

채택된 답변

Stephen23
Stephen23 2018년 5월 8일
편집: Stephen23 2018년 5월 8일
I don't really follow your code at all, but it seems to me that you would be better off using one simple non-scalar structure, rather then trying to nest structure with special fieldnames. Putting meta-data into fieldnames just makes accessing the data more difficult, especially when you try to loop over the structure later. I think you would be better off treating the meta-data as data in its own right and put it into fields as data, which then makes creating and accessing the structure simpler:
>> S = load('BinanceSymbols.mat');
>> Z = struct('name',S.BinanceSymbols);
>> [Z(:).timeFrame] = deal({'FourHours','TwelveHours','OneDay'});
And for example the first element of the structure:
>> Z(1).name
ans = ETHBTC
>> Z(1).timeFrame{1}
ans = FourHours
  댓글 수: 4
Stephen23
Stephen23 2018년 5월 8일
편집: Stephen23 2018년 5월 8일
You just need to loop over the fieldnames, and allocate TimeFrame to each field. Currently you are confusing the size of the structure with its fields, but these are two totally independent things. Your code:
for i = 1:length(data)
Coin(i).TimeFrame = TimeFrame;
end
makes little sense because before the loop Coin is a scalar structure (i.e. has size 1x1), and then within the loop you try to access its elements 2, 3, 4, etc. When you do this MATLAB will quietly expand the structure array to the size that you request (each new element has exactly the same fields, which are empty by default). But this is not what you really want: you need to loop over the fieldnames. You already have the fieldnames in the loaded data, so just use those:
S = load('BinanceSymbols.mat');
C = S.BinanceSymbols;
for k = 1:numel(C)
Coin.(C{k}) = TimeFrame;
end
Or you can get the fieldnames using the function... fieldnames.
As an alternative you can easily create the entire structure to include TimeFrame right from the start:
S = load('BinanceSymbols.mat');
C = S.BinanceSymbols;
C = reshape(C,1,[]);
C(2,:) = {TimeFrame};
Coin = struct(C{:});
Note that in both examples Coin is a scalar structure, because you want to use all of those names as different fieldnames. This means that once the structure exists the only way to add new data to those fields is to loop over the fieldnames. That is one reason why in my answer I recommended that you use a different approach: using a non-scalar structure and putting the meta-data into fields (not fieldnames) as real data. Then you can trivially access all elements of the structure without the awkward looping over all fieldnames, e.g. you could simply do this:
S = load('BinanceSymbols.mat');
C = S.BinanceSymbols;
Coin = struct('name',C); % create non-scalar structure
[Coin(:).TimeFrame] = deal(TimeFrame); % add TimeFrame
Note how much simpler the code is using a non-scalar structure, both in creating and accessing it. You can easily loop over its size (not its fieldnames), e.g. the first element of this structure is:
>> Coin(1).name
ans = ETHBTC
>> Coin(1).TimeFrame
ans = whatever you defined TimeFrame as
Read more:

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Structures에 대해 자세히 알아보기

태그

Community Treasure Hunt

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

Start Hunting!

Translated by