Constructing a string with several index requirements

73 views (last 30 days)
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 Comments
Stephen23
Stephen23 on 8 Nov 2024 at 16:43
"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'}
Voss
Voss on 8 Nov 2024 at 16:54
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'

Sign in to comment.

Accepted Answer

Star Strider
Star Strider on 8 Nov 2024 at 16:10
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 Comment
Voss
Voss on 8 Nov 2024 at 17:01
The square brackets are unnecessary when using string concatenation:
"S"+1
ans = "S1"
["S"+1]
ans = "S1"

Sign in to comment.

More Answers (3)

Voss
Voss on 8 Nov 2024 at 16:12
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.

Steven Lord
Steven Lord on 8 Nov 2024 at 16:35
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 Comments
Voss
Voss on 8 Nov 2024 at 18:03
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"

Sign in to comment.


Jason
Jason on 11 Nov 2024 at 13:08
Edited: Jason on 11 Nov 2024 at 13:14
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 Comments
Stephen23
Stephen23 on 11 Nov 2024 at 13:42
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)="

Sign in to comment.

Products


Release

R2023b

Community Treasure Hunt

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

Start Hunting!