How to use textscan on a cell array without a loop?

Hi everyone!
So, I have a structure with multiple fields. One of the fields I filled with strings from multiple, fairly large text files (~100,000 lines), and it is now a cell array. Here's the layout of the structure, and a sample of mystruct.out.
mystruct =
1×5 struct array with fields:
filename
out
size
mystruct.out =
{'%ACCDA,50,123.99,W,07512.001,E,2,11,2.2,1002.2,Z,,,,*22' }
{'%ACCDA,50,123.99,W,04412.001,E,2,11,2.2,1002.2,Z,,,,*20' }
{'%ACCDA,50,123.99,W,07112.001,E,2,11,2.2,1002.2,Z,,,,*2A' }
{'%ACCDA,50,123.99,W,08512.001,E,2,11,2.2,1002.2,Z,,,,*2E' }
{'%ACCDA,50,123.99,W,06512.001,E,2,11,2.2,1002.2,Z,,,,*2B' }
...
...
I want to avoid using a loop to perform the following, but I haven't been able to figure out how to do so on a mass scale without a loop.
I want to be able to use textscan, or some other method, to store the delimited strings into a new cell array, inside of an new mystruct field (like *** below)
Note: 'ii' is an index I'm using in a separate loop, but it's irrelevant to this issue.
for nlr = 1:mystruct(ii).size
fields = textscan(mystruct(ii).out{nlr},'%s','delimiter',',');
end
***(e.g. store into mystruct(ii).split(nlr))
How can I use textscan, or some other method, to "vectorize" the above loop?
Thanks!

댓글 수: 2

I am a little confused about the sizes involved. Your show a 1x5 struct array, and 5 example output lines, but imply that there are more. Is it that case that mystruct(K).out is a 1 x 1 cell array containing a character vector for any given K? Or is mystruct(K).out an N x 1 cell array containing character vectors for any given K? If mystruct(K).out is an N x 1 cell array of character vectors, then should the data for each be processed separately, or can it all be put together into one big array ?
rbme17
rbme17 2019년 8월 17일
편집: rbme17 2019년 8월 17일
Hi Walter, sorry for the confusion.
The size of the structure varies, but in this case it could be expanded like so:
mystruct(1) =
filename: some value
out: Nx1 array
size: some value
mystruct(2) = ... etc.
mystruct(K).out is an Nx1 cell array
I'm hoping to process each line of mystruct(K).out, from 1:N, and store it in the new structure field but without using a loop. Does that make more sense, or should I rephrase?
Thanks

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

 채택된 답변

rbme17
rbme17 2019년 8월 20일
편집: rbme17 2019년 8월 20일

0 개 추천

Ok, so I actually ended up figuring something out that doesn't require textscan. I used the function 'split'.
Here's a shortened sample:
mystruct.out = {
'%ACCDA,50,123.99,W,07512.001,E,2,11,2.2,1002.2,Z,,,,*22'
'%ACCDA,50,123.99,W,04412.001,E,2,11,2.2,1002.2,Z,,,,*20' };
s = split(mystruct(ii).out,',',1);
s =
{'%ACCDA' } {'%ACCDA' }
{'50' } {'50' }
{'123.99' } {'123.99' }
{'W' } {'W' }
{'07512.001'} {'04412.001'}
{'E' } {'E' }
{'2' } {'2' }
{'11' } {'11' }
{'2.2' } {'2.2' }
{'1002.2' } {'1002.2' }
{'Z' } {'Z' }
{0×0 char } {0×0 char }
{0×0 char } {0×0 char }
{0×0 char } {0×0 char }
{'*22' } {'*20' }
Sorry if I wasn't clear enough in what I was asking, I was able to accomplish what I needed too so thank you all for your help!

추가 답변 (2개)

Walter Roberson
Walter Roberson 2019년 8월 17일

1 개 추천

댓글 수: 3

Hmm this doesnt seem to be what I'm looking for. I don't need to join strings together, they need to be separated in order to be processed in another script.
textscan can process a character vector that has embedded newline characters, treating each as a separate line. The processing is quite efficient. This permits you to parse and convert each column of your input without having to loop sscanf or textscan over the cell entries. Give it a try.
mystruct.out = [{'%ACCDA,50,123.99,W,07512.001,E,2,11,2.2,1002.2,Z,,,,*22' }
{'%ACCDA,50,123.99,W,04412.001,E,2,11,2.2,1002.2,Z,,,,*20' }
{'%ACCDA,50,123.99,W,07112.001,E,2,11,2.2,1002.2,Z,,,,*2A' }
{'%ACCDA,50,123.99,W,08512.001,E,2,11,2.2,1002.2,Z,,,,*2E' }
{'%ACCDA,50,123.99,W,06512.001,E,2,11,2.2,1002.2,Z,,,,*2B' }];
S = strjoin(mystruct.out, '\n');
fields_cell = textscan(S, '%s%f%f%s%f%s%f%f%f%f%s%s%s%s%s', 'Delimiter', ',');
fields_cell{5}
ans =
7512.001
4412.001
7112.001
8512.001
6512.001

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

per isakson
per isakson 2019년 8월 17일
Am I on the right track? Run
%%
mystruct.out = {
'%ACCDA,50,123.99,W,07512.001,E,2,11,2.2,1002.2,Z,,,,*22'
'%ACCDA,50,123.99,W,04412.001,E,2,11,2.2,1002.2,Z,,,,*20'
'%ACCDA,50,123.99,W,07112.001,E,2,11,2.2,1002.2,Z,,,,*2A'
'%ACCDA,50,123.99,W,08512.001,E,2,11,2.2,1002.2,Z,,,,*2E'
'%ACCDA,50,123.99,W,06512.001,E,2,11,2.2,1002.2,Z,,,,*2B' };
%%
chr = strjoin( mystruct.out, '\n' );
cac = textscan( chr, repmat('%s',1,15), 'Delimiter',',' );
Inspect the result
>> cac{1}
ans =
5×1 cell array
{'%ACCDA'}
{'%ACCDA'}
{'%ACCDA'}
{'%ACCDA'}
{'%ACCDA'}
>> cac{3}
ans =
5×1 cell array
{'123.99'}
{'123.99'}
{'123.99'}
{'123.99'}
{'123.99'}
>> cac{15}
ans =
5×1 cell array
{'*22'}
{'*20'}
{'*2A'}
{'*2E'}
{'*2B'}
>>
Don't you want to convert the numeric fields to double?

댓글 수: 1

This was very close to what I needed. I ended up figuring out another way that worked well for me. Thanks!

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

카테고리

도움말 센터File Exchange에서 Multidimensional Arrays에 대해 자세히 알아보기

질문:

2019년 8월 17일

댓글:

2019년 8월 20일

Community Treasure Hunt

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

Start Hunting!

Translated by