Compose Yourself!
Even if we crunch numbers a lot, there are plenty of times, for example, when reporting, that we need to mix numbers into text. For a very long time, we've been able to create a character vector, and more recently, a string, with functions like sprintf. Look here for more information on character arrays and strings.
That's fine if we want to create one textual entity, but what if I need an array of them? I can use sprintf in a loop, or I can use a newer function, compose. Let me show you a bit how they each work.
Contents
A Single Numeric Input
Let's create some numeric values to use as possible inputs.
nums = [exp(1) pi]
nums = 2.7183 3.1416
Here's character output from sprintf:
cs1 = sprintf('%d', nums(2))
cs1 = '3.141593e+00'
And here's the equivalent string output:
ss1 = sprintf("%d", nums(2))
ss1 = "3.141593e+00"
Now let's try compose:
cc1 = compose('%d', nums(2))
cc1 = 1×1 cell array {'3.141593e+00'}
sc1 = compose("%d", nums(2)) % What do we have in our workspace? whos
sc1 = "3.141593e+00" Name Size Bytes Class Attributes ans 1x4 8 char cc1 1x1 136 cell ccm1 1x2 272 cell cs1 1x12 24 char csm1 1x26 52 char nums 1x2 16 double sc1 1x1 174 string scm1 1x2 252 string ss1 1x1 174 string ssm1 1x1 206 string tc 1x1 120 cell tmpc 1x2 228 cell tmps 1x2 4 char ts 1x2 4 char
What you may notice is that both sprintf and compose give the same output for the string version. However, for the character output, we get one character array using sprintf, but that same array embedded in a cell using compose.
clearvars -except nums
Multiple Numeric Inputs
Now let's see what happens if we are formatting output with more than a single numeric input.
csm1 = sprintf('%d ',nums) ssm1 = sprintf("%d ",nums) ccm1 = compose('%d',nums) scm1 = compose("%d",nums)
csm1 = '2.718282e+00 3.141593e+00 ' ssm1 = "2.718282e+00 3.141593e+00 " ccm1 = 1×2 cell array {'2.718282e+00'} {'3.141593e+00'} scm1 = 1×2 string array "2.718282e+00" "3.141593e+00"
whos
Name Size Bytes Class Attributes ccm1 1x2 272 cell csm1 1x26 52 char nums 1x2 16 double scm1 1x2 252 string ssm1 1x1 206 string
What we see is that we get exactly the same types of output as before. But for the string version with compose, we get output matching the dimensions of the input, in this case, 1x2, whereas with the sprintf version, we get a single array for all of the cases. sprintf always produces a single array as output and recycles the hole (the formatter) while there is more data to format. compose returns arrays of text.
Handling Holes
Again, sprintf produces one output, regardless of the dimensions of the input.
tmps = sprintf('%d',[1 2]) tmpc = compose('%d',[1 2])
tmps = '12' tmpc = 1×2 cell array {'1'} {'2'}
Also, sprintf truncates a hole if you don’t provide data. compose leaves it there in case you want to fill it with a subsequent call:
ts = sprintf('\n %s') tc = compose('\n %s')
ts = ' ' tc = 1×1 cell array {'↵ %s'}
Your Turn
Do you need to format text/numbers? What techniques do you use to get the results you want? Let us know here.
- Category:
- Strings