Search code examples
arraysstringmatlabdoublecell

Matlab: Converting a double vector array to string cell array


map1 = containers.Map({'212','2','12','44'},[4,5,6,7]);
keyset = str2double(keys(map1));

Now I do a set of operations on the keyset which will give back

Keyset= [203,2,12,39];

I tired the following:

num2cell(num2str(keyset));
num2cell(num2str(keyset,1));
num2cell(num2str(keyset,'%11.0g'));
num2cell(num2str(keyset,3));

all of the above gave weird results in the final cell array. I just need the integers to be used as keys for another container map.


Solution

  • I propose 5 additional solutions, three of which are 4-5x faster by than the solutions proposed so far. The lessons learned from this are:

    • num2str is slow
    • cellfun and arrayfun can add significant overhead
    • There are many ways to convert a numeric array to a cell array of strings.

    The three highest-performance solutions are very similar in terms of performance:

    Looping to assign cell elements

    n4 = length(Keyset);
    tmp4 = cell(n4,1);
    for i4 = 1:n4
        tmp4{i4} = sprintf('%i',Keyset(i4));
    end
    

    Converting all to string and calling textscan

    tmp6 = textscan(sprintf('%i\n',Keyset'),'%s');
    tmp6 = tmp6{1};
    

    Converting all to string and calling regexp.

    tmp3 = regexp(sprintf('%i ',Keyset),'(\d+)','match');
    

    Here's the full test code with timings:

    function t = speedTest
    
    t=zeros(7,1);
    for ii=1:100, 
        Keyset=randi(1,10,100); % random keys
        tic; 
        eval( [ 'tmp1 = { ', sprintf(' %d ', Keyset), ' }; '] );
        t(1)=t(1)+toc; 
        tic;
        tmp2=arrayfun(@num2str, Keyset, 'Uniform', false);
        t(2)=t(2)+toc;
    
        tic;
        tmp3 = regexp(sprintf('%i ',Keyset),'(\d+)','match');
        t(3) = t(3)+toc;
    
        tic;
        n4 = length(Keyset);
        tmp4 = cell(n4,1);
        for i4 = 1:n4
            tmp4{i4} = sprintf('%i',Keyset(i4));
        end
        t(4) = t(4)+toc;
    
        tic;
        n5 = length(Keyset);
        tmp5 = cell(n5,1);
        for i5 = 1:n5
            tmp4{i5} = num2str(Keyset(i5));
        end
        t(5) = t(5)+toc;
    
        tic;
        tmp6 = textscan(sprintf('%i\n',Keyset'),'%s');
        tmp6 = tmp6{1};
        t(6) = t(6)+toc;
    
        tic;
        tmp7 = num2cell(Keyset);
        tmp7 = cellfun(@(x)sprintf('%i',x),tmp7,'uni',false);
        t(7) = t(7)+toc;
    
    
    end;
    t
    
    t =
    
        1.7820
       21.7201
        0.4068
        0.3188
        2.2695
        0.3488
        5.9186