Matlab concatenate variable string without curly braces - arrays

I'm trying to concatenate a series of strings in a loop into a variable array but the resulting strings are always within curly braces. Why does this happen, and how can I concatenate the string without them? Thanks
subs = {'abc001' 'abc002' 'abc003' 'abc004'};
for i = 1:size(subs,2)
subject = subs(i);
files_in(i).test = strcat('/home/data/','ind/',subject,'/test_ind_',subject,'.mat');
end
files_in(1)
% ans =
% test: {'/home/data/ind/abc001/test_ind_abc001.mat'}
I would like it to be:
test: '/home/data/ind/abc001/test_ind_abc001.mat'

subs is a cell array. If you index it using () notation, you will also get a cell array.
a = {'1', '2', '3'};
class(a(1))
% cell
To get the string inside the cell array you need to use {} notation to index into it.
class(a{1})
% char
When you use strcat with cell arrays, the result will be a cell array. When you use it with strings, the resut will be a string. So if we switch out (k) with {k} we get what you expect.
for k = 1:numel(subs)
subject = subs{k};
files_in(k).test = strcat('/home/data/ind/', subject, '/test_ind_', subject, '.mat');
end
A few side notes:
Don't use i as a variable. i and j are used in MATLAB to indicate sqrt(-1).
It is recommended to use fullfile to construct file paths rather than strcat.

Related

Efficient way to filter an array based on element index

I have an array of arrays. So each element of my first array contains a comma separated list of values. If I use the split function, I can get an array from this comma separated list. What I need to do is filter out this second array based on element position. For example only keep columns one, three, five and nine.
One way to do this is loop thru my first array, for each element do a split on the element to get my second array. Then loop thru this second array, increment a counter to track the current element index. If the counter is equal to one of the columns I want to keep, then concat the element to a string variable.
This is very inefficient and takes forever to run on large arrays. Does anyone have any ideas on a better way to do this? I hope I explained this clearly.
There are some built in array actions like “Filter” and “Join” as you mention, but for something this specific I imagine you’ll need to call some code (e.g. azure function) to quickly do manipulation and return result
For the first loop I don't know of any alternate but for second loop, Instead of looping through the second array,you can simply access the elements with index that you require.
Assuming the size is not an issue.
string[] Arr1 = new string[] { "0_zero,0_One,0_Two,0_Three,0_Four,0_Five,0_six,0_seven,0_eight,0_nine",
"1_zero,1_One,1_Two,1_Three,1_Four,1_Five,1_six,1_seven,1_eight,1_nine" };
string myString = string.Empty;
foreach(var a in Arr1)
{
var sp = a.Split(',');
myString= string.Concat(myString, sp[0], sp[3], sp[5], sp[9]);
}
Console.WriteLine(myString); //gives "0_One0_Three0_Five0_nine1_One1_Three1_Five1_nine"
In case we're not sure of length of each string, we can use if else ladder with decreasing order from maximum index that we want to use like so
foreach(var a in Arr1)
{
var sp = a.Split(',');
int len = sp.Length;
if (len >= 10) myString= string.Concat(myString, sp[1], sp[3], sp[5], sp[9]);
else if (len >= 6) myString = string.Concat(myString, sp[1], sp[3], sp[5]);
else if (len >= 4) myString = string.Concat(myString, sp[1], sp[3]);
else if (len >= 2) myString = string.Concat(myString, sp[1]);
}
So that we don't face IndexOutofBoundsException

storing the longest string after strsplit

I am trying to store the longest resultant string after using the function strsplit unable to do so
eg: I have input strings such as
'R.DQDEGNFRRFPTNAVSMSADENSPFDLSNEDGAVYQRD.L'or
'L.TSNKDEEQRELLKAISNLLD'
I need store the string only between the dots (.)
If there is no dot then I want the entire string.
Each string may have zero, one or two dots.
part of the code which I am using:
for i=1:700
x=regexprep(txt(i,1), '\([^\(\)]*\)','');
y=(strsplit(char(x),'.'));
for j=1:3
yValues(1,j)=y{1,j};
end
end
But the string yValues is not storing the value of y, instead showing the following error:
Assignment has more non-singleton rhs dimensions than non-singleton subscripts
What am I doing wrong and are there any suggestions on how to fix it?
The issue is that y is a cell array and each element contains an entire string and it therefore can't be assigned to a single element in a normal array yvalues(1,j).
You need yvalues to be a cell array and then you can assign into it just fine.
yValues{j} = y{j};
Or more simply
% Outside of your loop
yValues = cell(1,3);
% Then inside of your loop
yValues(j) = y(j);
Alternately, if you just want the longest output of strsplit, you can just do something like this.
% Split the string
parts = strsplit(mystring, '.');
% Find the length of each piece and figure out which piece was the longest
[~, ind] = max(cellfun(#numel, parts));
% Grab just the longest part
longest = parts{ind};

How to convert array of strings to string in D?

I have got array of strings like:
string [] foo = ["zxc", "asd", "qwe"];
I need to create string from them. Like:
"zxc", "asd", "qwe" (yes every elements need be quoted and separate with comma from another, but it should be string, but not array of strings.
How can I do it's in functional style?
import std.algorithm, std.array, std.string;
string[] foo = ["zxc", "asd", "qwe"];
string str = foo.map!(a => format(`"%s"`, a)).join(", ");
assert(str == `"zxc", "asd", "qwe"`);
std.algorithm.map takes a lambda which converts an element in the range into something else, and it returns a lazy range where each element is the result of passing an element from the original range to the lambda function. In this case, the lambda takes the input string and creates a new string which has quotes around it, so the result of passing foo to it is a range of strings which have quotes around them.
std.array.join then takes a range and eagerly concatenates each of its elements with the given separator separating each one and returns a new array, and since it's given a range of strings it returns a string. So, by giving it the result of the call to map and ", " for the separator, you get your string made up of the original strings quoted and separated by commas.
std.algorithm.joiner would do the same thing as join, except that it results in a lazy range instead of an array.
Alternatively, use std.string.format
Your format specifier should be something like this:
auto joinedstring = format("%(\“%s\",%)", stringarray)
this is untested as I'm on mobile, but it's something similar to it!

Is there an idiomatic way to exchange two elements in a cell array?

I know that I can write it like this:
tmp = arr{i}
arr{i} = arr{j}
arr{j} = tmp
But is there a simpler way? For instance, in Python I'd write:
arr[i], arr[j] = arr[j], arr[i]
Standard, idiomatic way:
Use a vector of indices:
arr([i j]) = arr([j i]); %// arr can be any array type
This works whether arr is a cell array, a numerical array or a string (char array).
Not recommended (but possible):
If you want to use a syntax more similar to that in Python (with a list of elements instead of a vector of indices), you need the deal function. But the resulting statement is more complicated, and varies depending on whether arr is a cell array or a standard array. So it's not recommended (for exchanging two elements). I include it only for completeness:
[arr{i}, arr{j}] = deal(arr{j}, arr{i}); %// for a cell array
[arr(i), arr(j)] = deal(arr(j), arr(i)); %// for a numeric or char array
Not to confuse things, but let me another syntax:
[arr{[i,j]}] = arr{[j,i]};
or
[arr{i},arr{j}] = arr{[j,i]};
The idea here is to use comma-separated lists with curly-braces indexing.
Remember that when working with cell-arrays, ()-indexing gives you a sliced cell-array, while {}-indexing extracts elements from the cell-array and the return type is whatever was stored in the specified cell (when the index is non-scalar, MATLAB returns each cell content individually as a comma-separated list).

Arrays containing text in MATLAB

In MATLAB, when code like this is implemented:
c = ['a','b','c','d'];
you can't really do anything with the elements. To illustrate my example:
>> c
c =
abcd
and when you do c(1,1) it returns A. But for c(2,1) it returns Index exceeds matrix dimensions.
To combat this problem, is there any way I could get around it? Or perhaps a different type of array?
You need to store each string in a different row, like so:
c = ['a';'b';'c';'d'];
What you have done above is use the [], which is the string concatenation operator. What it outputs is a single string, 'abcd', stored in c(1), which is why c(2) throws an index error.
Alternatively, you could use cell arrays :
c{1} = 'a';
c{2} = 'b';

Resources