Constructing a string with several index requirements

Hello, I have a vector of numbers r2 that I need to send over a communciation to an array (called ScanArray). The comms is such that I can only send upto 50 elements in each send (Im using writeline)
Heres the 1st 8 values I need to send
r2 =
0 30 60 90 120 150 180 210
and heres my string that I construct that I send with writeline function
command=['ScanArray(0)(0)=',num2str(r2(1,1)),'ScanArray(0)(1)=',num2str(r2(1,2)),'ScanArray(0)(2)=',num2str(r2(1,3)),'ScanArray(0)(3)=',num2str(r2(1,4))]
Rather than write this out for 50 elements ScanArray(0)(0) -> ScanArray(0)(49), is there a more effcient way to construct this. This was my attemp:
command=[];
for i=1:50
commandnew=['ScanArray(0)(',num2str(i),')=',num2str(r2(1,i))]
command=[command,commandnew]
end

2 commentaires

"is there a more effcient way to construct this."
Do not fight MATLAB with loops. Use e.g. strings or COMPOSE:
r2 = 0:30:210;
ix = 1:numel(r2);
tx = "ScanArray(0)(" + ix(:) + ")=" + r2(:)
tx = 8x1 string array
"ScanArray(0)(1)=0" "ScanArray(0)(2)=30" "ScanArray(0)(3)=60" "ScanArray(0)(4)=90" "ScanArray(0)(5)=120" "ScanArray(0)(6)=150" "ScanArray(0)(7)=180" "ScanArray(0)(8)=210"
tx = compose('ScanArray(0)(%u) = %u',ix(:),r2(:))
tx = 8x1 cell array
{'ScanArray(0)(1) = 0' } {'ScanArray(0)(2) = 30' } {'ScanArray(0)(3) = 60' } {'ScanArray(0)(4) = 90' } {'ScanArray(0)(5) = 120'} {'ScanArray(0)(6) = 150'} {'ScanArray(0)(7) = 180'} {'ScanArray(0)(8) = 210'}
r2 = 0:30:210;
ix = 0:numel(r2)-1;
tx = "ScanArray(0)(" + ix(:) + ")=" + r2(:);
tx = [tx{:}]
tx = 'ScanArray(0)(0)=0ScanArray(0)(1)=30ScanArray(0)(2)=60ScanArray(0)(3)=90ScanArray(0)(4)=120ScanArray(0)(5)=150ScanArray(0)(6)=180ScanArray(0)(7)=210'
tx = compose('ScanArray(0)(%u)=%u',ix(:),r2(:));
tx = [tx{:}]
tx = 'ScanArray(0)(0)=0ScanArray(0)(1)=30ScanArray(0)(2)=60ScanArray(0)(3)=90ScanArray(0)(4)=120ScanArray(0)(5)=150ScanArray(0)(6)=180ScanArray(0)(7)=210'

Connectez-vous pour commenter.

 Réponse acceptée

I’m not certain what you need, however this is one option —
r2 = [0 30 60 90 120 150 180 210];
command=['ScanArray(0)(0)=',num2str(r2(1,1)),'ScanArray(0)(1)=',num2str(r2(1,2)),'ScanArray(0)(2)=',num2str(r2(1,3)),'ScanArray(0)(3)=',num2str(r2(1,4))]
command = 'ScanArray(0)(0)=0ScanArray(0)(1)=30ScanArray(0)(2)=60ScanArray(0)(3)=90'
for k = 1:numel(r2)-3
command = ["ScanArray(0)("+(k-1)+")="+r2(1,k)+"ScanArray(0)("+k+")="+r2(1,k+1)+"ScanArray(0)("+(k+1)+")="+r2(1,k+2)+"ScanArray(0)("+(k+2)+")="+r2(1,k+3)]
end
command = "ScanArray(0)(0)=0ScanArray(0)(1)=30ScanArray(0)(2)=60ScanArray(0)(3)=90"
command = "ScanArray(0)(1)=30ScanArray(0)(2)=60ScanArray(0)(3)=90ScanArray(0)(4)=120"
command = "ScanArray(0)(2)=60ScanArray(0)(3)=90ScanArray(0)(4)=120ScanArray(0)(5)=150"
command = "ScanArray(0)(3)=90ScanArray(0)(4)=120ScanArray(0)(5)=150ScanArray(0)(6)=180"
command = "ScanArray(0)(4)=120ScanArray(0)(5)=150ScanArray(0)(6)=180ScanArray(0)(7)=210"
It may be necessary to expand on that, perhaps with a nested loop, for a multi-row ‘r2’.
.

1 commentaire

The square brackets are unnecessary when using string concatenation:
"S"+1
ans = "S1"
["S"+1]
ans = "S1"

Connectez-vous pour commenter.

Plus de réponses (3)

r2 = [0 30 60 90 120 150 180 210];
command = sprintf('ScanArray(0)(%d)=%g',[0:numel(r2)-1; r2])
command = 'ScanArray(0)(0)=0ScanArray(0)(1)=30ScanArray(0)(2)=60ScanArray(0)(3)=90ScanArray(0)(4)=120ScanArray(0)(5)=150ScanArray(0)(6)=180ScanArray(0)(7)=210'
The %g is to handle cases where elements of r2 are not integers. If they are always integers you can use %d there instead.
And I don't know but you may need a delimiter between adjacent ScanArray(0) assignments, as in
command = sprintf('ScanArray(0)(%d)=%g ',[0:numel(r2)-1; r2])
command = 'ScanArray(0)(0)=0 ScanArray(0)(1)=30 ScanArray(0)(2)=60 ScanArray(0)(3)=90 ScanArray(0)(4)=120 ScanArray(0)(5)=150 ScanArray(0)(6)=180 ScanArray(0)(7)=210 '
or
command = sprintf('ScanArray(0)(%d)=%g;',[0:numel(r2)-1; r2])
command = 'ScanArray(0)(0)=0;ScanArray(0)(1)=30;ScanArray(0)(2)=60;ScanArray(0)(3)=90;ScanArray(0)(4)=120;ScanArray(0)(5)=150;ScanArray(0)(6)=180;ScanArray(0)(7)=210;'
etc.
r2 = [0 30 60 90 120 150 180 210];
ind = 0:numel(r2)-1;
result = join("ScanArray(0)(" + ind + ")=" + r2, newline)
result =
"ScanArray(0)(0)=0 ScanArray(0)(1)=30 ScanArray(0)(2)=60 ScanArray(0)(3)=90 ScanArray(0)(4)=120 ScanArray(0)(5)=150 ScanArray(0)(6)=180 ScanArray(0)(7)=210"
Replace newline with ";" to join the substrings with semicolons rather than newlines (which I used so you can easily see the individual substrings included in result.)

4 commentaires

Jason
Jason le 8 Nov 2024
Modifié(e) : Jason le 8 Nov 2024
Thanks Steven (and everyone else, quite a few nice ways)
i've just realised I need to change my request slightly, what now if I wanted the output to have the 2nd argument in the array index to vary only from 0 to 3 and then increment the 1st index. Upto 48 total elements
The values should still equate to the 1D vector (R1) values:
r2 = [0 30 60 90 120 150 180 210 .... 500];
result =
"ScanArray(0)(0)=0
ScanArray(0)(1)=30
ScanArray(0)(2)=60
ScanArray(0)(3)=90
ScanArray(1)(1)=120
ScanArray(1)(2)=150
ScanArray(1)(3)=180
ScanArray(1)(4)=210
……
ScanArray(3)(4)=500 "
I basically want to populate my array in this order:
I do have to go upto column number 9399, but I need to send the data in chuncks of 50 or less, so 48 in this case. After the 1st 48 elements being filled, R1 will reset so will need to reset its index.
Thanks
Jason
r2 = (0:47)*30;
N = numel(r2);
n = 4;
assert(mod(N,n) == 0)
[idx1,idx2] = meshgrid(0:N/n-1,0:n-1)
idx1 = 4×12
0 1 2 3 4 5 6 7 8 9 10 11 0 1 2 3 4 5 6 7 8 9 10 11 0 1 2 3 4 5 6 7 8 9 10 11 0 1 2 3 4 5 6 7 8 9 10 11
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
idx2 = 4×12
0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
result = join("ScanArray("+idx1(:)+")("+idx2(:)+")="+r2(:),newline())
result =
"ScanArray(0)(0)=0 ScanArray(0)(1)=30 ScanArray(0)(2)=60 ScanArray(0)(3)=90 ScanArray(1)(0)=120 ScanArray(1)(1)=150 ScanArray(1)(2)=180 ScanArray(1)(3)=210 ScanArray(2)(0)=240 ScanArray(2)(1)=270 ScanArray(2)(2)=300 ScanArray(2)(3)=330 ScanArray(3)(0)=360 ScanArray(3)(1)=390 ScanArray(3)(2)=420 ScanArray(3)(3)=450 ScanArray(4)(0)=480 ScanArray(4)(1)=510 ScanArray(4)(2)=540 ScanArray(4)(3)=570 ScanArray(5)(0)=600 ScanArray(5)(1)=630 ScanArray(5)(2)=660 ScanArray(5)(3)=690 ScanArray(6)(0)=720 ScanArray(6)(1)=750 ScanArray(6)(2)=780 ScanArray(6)(3)=810 ScanArray(7)(0)=840 ScanArray(7)(1)=870 ScanArray(7)(2)=900 ScanArray(7)(3)=930 ScanArray(8)(0)=960 ScanArray(8)(1)=990 ScanArray(8)(2)=1020 ScanArray(8)(3)=1050 ScanArray(9)(0)=1080 ScanArray(9)(1)=1110 ScanArray(9)(2)=1140 ScanArray(9)(3)=1170 ScanArray(10)(0)=1200 ScanArray(10)(1)=1230 ScanArray(10)(2)=1260 ScanArray(10)(3)=1290 ScanArray(11)(0)=1320 ScanArray(11)(1)=1350 ScanArray(11)(2)=1380 ScanArray(11)(3)=1410"
Or:
r2 = (0:47)*30;
N = numel(r2);
n = 4;
assert(mod(N,n) == 0)
result = strjoin("ScanArray("+(0:N/n-1)+")("+(0:n-1).'+")="+reshape(r2,n,[]),newline())
result =
"ScanArray(0)(0)=0 ScanArray(0)(1)=30 ScanArray(0)(2)=60 ScanArray(0)(3)=90 ScanArray(1)(0)=120 ScanArray(1)(1)=150 ScanArray(1)(2)=180 ScanArray(1)(3)=210 ScanArray(2)(0)=240 ScanArray(2)(1)=270 ScanArray(2)(2)=300 ScanArray(2)(3)=330 ScanArray(3)(0)=360 ScanArray(3)(1)=390 ScanArray(3)(2)=420 ScanArray(3)(3)=450 ScanArray(4)(0)=480 ScanArray(4)(1)=510 ScanArray(4)(2)=540 ScanArray(4)(3)=570 ScanArray(5)(0)=600 ScanArray(5)(1)=630 ScanArray(5)(2)=660 ScanArray(5)(3)=690 ScanArray(6)(0)=720 ScanArray(6)(1)=750 ScanArray(6)(2)=780 ScanArray(6)(3)=810 ScanArray(7)(0)=840 ScanArray(7)(1)=870 ScanArray(7)(2)=900 ScanArray(7)(3)=930 ScanArray(8)(0)=960 ScanArray(8)(1)=990 ScanArray(8)(2)=1020 ScanArray(8)(3)=1050 ScanArray(9)(0)=1080 ScanArray(9)(1)=1110 ScanArray(9)(2)=1140 ScanArray(9)(3)=1170 ScanArray(10)(0)=1200 ScanArray(10)(1)=1230 ScanArray(10)(2)=1260 ScanArray(10)(3)=1290 ScanArray(11)(0)=1320 ScanArray(11)(1)=1350 ScanArray(11)(2)=1380 ScanArray(11)(3)=1410"
Thankyou!

Connectez-vous pour commenter.

Jason
Jason le 11 Nov 2024
Modifié(e) : Jason le 11 Nov 2024
Could i ask how I would make the double for loop work using idexing:
I start with this:
jx=1:4;
ix=0:3
tx = "ScanArray(0)(" + ix(:) + ")="
This correctly gives me this:
tx =
4×1 string array
"ScanArray(0)(0)="
"ScanArray(0)(1)="
"ScanArray(0)(2)="
"ScanArray(0)(3)="
Now I want the first index to increment also by the jx term (still loop the 2nd index 0,1,2,3)
I tried this:
tx(jx) = "ScanArray("+jx(:)-1+")(" + ix(:) + ")="

4 commentaires

Thst should work essentially as you wrote it.
The only change I made here is to enclose the arithmetic operation in parentheses —
jx = 1:4
jx = 1×4
1 2 3 4
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
ix = 0:3
ix = 1×4
0 1 2 3
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
tx(jx,:) = "ScanArray("+(jx(:)-1)+")(" + ix(:) + ")="
tx = 4x1 string array
"ScanArray(0)(0)=" "ScanArray(1)(1)=" "ScanArray(2)(2)=" "ScanArray(3)(3)="
.
thanks, but I need
ScanArray(0)(0)=
ScanArray(0)(1)=
ScanArray(0)(2)=
ScanArray(0)(3)=
ScanArray(1)(0)=
ScanArray(1)(1)=
ScanArray(1)(2)=
ScanArray(1)(3)=
ScanArray(2)(0)=
ScanArray(2)(1)=
etc
jx = 1:4;
ix = 0:3;
tx = "ScanArray("+(jx-1)+")("+ix(:)+")=";
tx = tx(:)
tx = 16x1 string array
"ScanArray(0)(0)=" "ScanArray(0)(1)=" "ScanArray(0)(2)=" "ScanArray(0)(3)=" "ScanArray(1)(0)=" "ScanArray(1)(1)=" "ScanArray(1)(2)=" "ScanArray(1)(3)=" "ScanArray(2)(0)=" "ScanArray(2)(1)=" "ScanArray(2)(2)=" "ScanArray(2)(3)=" "ScanArray(3)(0)=" "ScanArray(3)(1)=" "ScanArray(3)(2)=" "ScanArray(3)(3)="
Thankyou!

Connectez-vous pour commenter.

Produits

Version

R2023b

Community Treasure Hunt

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

Start Hunting!

Translated by