简体   繁体   中英

matlab adding a string to each element of a numeric vector

I need to switch between a vector of numerics and a vector of strings:

a = [1, 2, 4, 5]
b = {'xx1', 'xx2', 'xx3', 'xx4'}

I tried strcat('XX', num2str(a)) , but it returns XX1 2 3 4 5 , which is not what I want. Can someone tell me how to create b from a and how to create a from b ? Thanks!

No need for loops or cellfun . Let

a = [1, 2, 4, 15];
b = {'xx1', 'xx2', 'xx4', 'xx15'};

From b to a

Convert a to a cell array of strings using num2str with format specifier '%-i' to exploit the fact that cellstr ignores trailing spaces; and after using the latter concatenate via strcat :

b_from_a = strcat('xx', cellstr(num2str(a(:), '%-i'))).';

From a to b

Delete xx from each string using strrep , then apply str2double :

a_from_b = str2double(strrep(b, 'xx', ''));

B FROM A

There is an undocumented Matlab function that I love to use and works perfectly in this kind of situations: sprintfc . It's lightning-fast and allows to convert numerical vectors into cell vectors of characters arrays using a custom format:

a = [1, 2, 4, 5];
b = sprintfc('xx%d',a)

b =
    1×4 cell array
    'xx1'   'xx2'   'xx4'   'xx5'

A FROM B

This is pretty simple using a replacement:

b = {'xx1', 'xx2', 'xx3', 'xx4'};
a = str2double(strrep(b,'xx',''))

a =
    1     2     3     4

Solution 1

without loop you can using cellfun :

xxs = cell(1,4);
xxs(:) = 'XX';
q = cell(1,4); q{1}=1;q{2}=2;q{3}=4;q{4}=5;
result = cellfun(@(x,i) strcat(x, num2str(i)), xxs,q, 'UniformOutput', false);

Solution 2

Using loop:

a = [1 2 4 5];
result = cell(1,length(a));
for i = 1:length(a)
     result{i} = strcat('XX',num2str(a(i)));
end 

If you're open using a loop instead of vectorized functions, it could be done fairly easily. For example:

clc; clear;

a = [1, 2, 4, 5];
for i = 1:length(a)
    b{i} = strcat('XX', num2str(a(i)));
end
b

returns

b =

  1×4 cell array

{'XX1'}    {'XX2'}    {'XX4'}    {'XX5'}

If you want to go the other way, you could do this.

for i = 1:length(b)
    c(i) = str2double(b{i}(3:end));
end
c

which returns

c =

     1     2     4     5

It's worth noting here that better code would pre-allocate both b and c .

In 16b MATLAB added a new string class and in 17a you can construct a string from double quotes. Using string,

"xx" + a

would give you the desired answer. Here is a performance comparison of string against the other solutions:

>> profFunc
matlabbit solution: 0.29956
Luis Mendo solution: 15.2378
OmG solution 1: 41.0055
OmG solution 2: 29.1976
Tommaso Belluzzo solution: 1.3574


function  profFunc

    a = [1, 2, 4, 5];

    n = 1E5;

    tic;
    for i = 1:n
        ans = "xx" + a;
    end
    disp("matlabbit solution: " + toc);

    tic;
    for i = 1:n
        ans = strcat('xx', cellstr(num2str(a(:), '%-i'))).';
    end
    disp("Luis Mendo solution: " + toc);

    tic;
    for i = 1:n
        xxs = cell(1,4);
        xxs(:) = {'XX'};
        q = cell(1,4); q{1}=1;q{2}=2;q{3}=4;q{4}=5;
        ans = cellfun(@(x,i) strcat(x, num2str(i)), xxs,q, 'UniformOutput', false);
    end
    disp("OmG solution 1: " + toc);

    tic;
    for i = 1:n
        ans = cell(1,length(a));
        for i = 1:length(a)
             ans{i} = strcat('XX',num2str(a(i)));
        end 
    end
    disp("OmG solution 2: " + toc);

    tic;
    for i = 1:n
        ans = sprintfc('xx%d',a);
    end
    disp("Tommaso Belluzzo solution: " + toc);
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM