sscanf with cell array of strings

18 views (last 30 days)
Rub Ron
Rub Ron on 1 Sep 2020
Commented: Bruno Luong on 2 Sep 2020
Say I have a cell array:
C = {'2_5_7';'10_2_6';'4_3_7';'3_10_11';'3_16_11'};
To extract one row as a vector of number I was using:
sscanf(C{[2]},'%d_')'
ans =
10 2 6
Now I would like to get several rows (say 2 and 4) in form of a matrix, but this does not work.
sscanf(C{[2 4]},'%d_')'
The desired output for this case should be:
ans =
10 2 6
3 10 11
I would like to avoid the use of a for loop.Any suggestions?
EDIT: The elements of C dont necesarilly contain only 3 number, they can contain 4 or more. ie '3_10_11_5'
  2 Comments
Bruno Luong
Bruno Luong on 1 Sep 2020
I tell you a secret: For-loop is your true friend, Arrayfun/cellfun are your fake friends.
Bruno Luong
Bruno Luong on 1 Sep 2020
If C contains strings coding different lengths, you cannot put the result in an array, but cell array.

Sign in to comment.

Accepted Answer

Stephen23
Stephen23 on 1 Sep 2020
Edited: Stephen23 on 1 Sep 2020
Probably the most efficient solution:
>> C = {'2_5_7';'10_2_6';'4_3_7';'3_10_11';'3_16_11'};
>> X = [2,4];
>> M = sscanf(sprintf(' %s',C{X}),'%d_%d_%d',[3,Inf]).'
M =
10 2 6
3 10 11
Or a slight simplification (if you are confident about your data):
>> M = sscanf(sprintf('%s_',C{X}),'%d_',[3,Inf]).'
M =
10 2 6
3 10 11
  4 Comments
Rub Ron
Rub Ron on 1 Sep 2020
I found this way. Perhpas if there is a more straight way of doin it.
cell2mat(cellfun(@(s)sscanf(s,'%d_')', C([2 4]), 'UniformOutput', false))
Stephen23
Stephen23 on 1 Sep 2020
Edited: Stephen23 on 1 Sep 2020
"Perhpas if there is a more straight way of doin it."
Yes, the way I showed you.
Using cellfun and cell2mat will be less efficient than what I showed you. Lets try it (1e4 iterations):
Elapsed time is 0.917299 seconds. % my code
Elapsed time is 4.073263 seconds. % your code

Sign in to comment.

More Answers (1)

Bruno Luong
Bruno Luong on 1 Sep 2020
Edited: Bruno Luong on 1 Sep 2020
>> C = {'2_5_7';'10_2_6';'4_3_7';'3_10_11';'3_16_11_12_20'}
C =
5×1 cell array
{'2_5_7' }
{'10_2_6' }
{'4_3_7' }
{'3_10_11' }
{'3_16_11_12_20'}
>> A = cellfun(@str2num, strrep(C([1,5]),'_',','), 'unif', 0)
A =
2×1 cell array
{1×3 double}
{1×5 double}
>> A{:}
ans =
2 5 7
ans =
3 16 11 12 20
  2 Comments
Rub Ron
Rub Ron on 1 Sep 2020
I was trying to use this form cellfun(@str2num, strrep(C([1,5]),'_',','), 'unif', 0) to get a double instead of a cell, because in my case the elements of the cell array have the same amount of numbers.
Bruno Luong
Bruno Luong on 2 Sep 2020
If they have the same number of elements, e.g.
C = {'2_5_7';'10_2_6';'4_3_7';'3_10_11';'3_16_11_12_20'}
you can do
substring=char(C([1,3]));
substring(substring=='_')=',';
str2num(substring)
% or
str2num(char(strrep(C([1,4]),'_',',')))

Sign in to comment.

Categories

Find more on Data Type Conversion 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!