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

9 ビュー (過去 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
  2 件のコメント
Stephen23
Stephen23 2018 年 5 月 8 日
@Erik Nyström: please upload 'BinanceSymbols.mat' by clicking on the paperclip button.

サインインしてコメントする。

採用された回答

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 Center および File ExchangeStructures についてさらに検索

タグ

Community Treasure Hunt

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

Start Hunting!

Translated by