MATLAB Answers

sscanf with cell array of strings

9 views (last 30 days)
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

Stephen Cobeldick
Stephen Cobeldick on 1 Sep 2020
Edited: Stephen Cobeldick 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

Show 1 older comment
Stephen Cobeldick
Stephen Cobeldick on 1 Sep 2020
Based on the edit to the original question, where this information was added "The elements of C dont necesarilly contain only 3 number, they can contain 4 or more. ie '3_10_11_5'", assuming that all cells contain strings with the same number of numbers, then you can simply adust for the size automatically:
N = numel(sscanf(C{1},'%d_'));
M = sscanf(sprintf('%s_',C{X}),'%d_',[N,Inf]).'
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))
Stephen Cobeldick
Stephen Cobeldick 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.

Community Treasure Hunt

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

Start Hunting!