Storing strings of different sizes in a MATLAB array? - arrays

I want to be able to store a series of strings of different sizes such as
userinput=['AJ48 NOT'; 'AH43 MANA'; 'AS33 NEWEF'];
This of course returns an error as the number of columns differs per row. I'm aware that all that is needed for this to work is adequate spaces in the first and second rows. However I need to be able to put this into an array without forcing the user to add these spaces on his/her own. Is there a command that allows me to do this? If possible I'd also like to know why this problem doesn't arise with numbers e.g.
a=[1; 243; 23524];

You cannot do this with standard Matlab arrays. A string is really just a vector of characters in Matlab. And you cannot have a matrix with rows of different lengths.
You can, however, use a cell array:
userinput={'AJ48 NOT'; 'AH43 MANA'; 'AS33 NEWEF'};
disp(userinput{1});
Be aware that there are many situations where cell arrays don't work like normal arrays.

To just answer to your last part of your question; simply because strings may be variable length but numbers (in Matlab) are fixed length. It's one of the main ideas of arrays to let them hold only fixed sizes entities (for example because the need of efficient look up), see more on the topic here.

Related

Fetch different columns from different google sheets using Query [duplicate]

When I append arrays in google spreadsheets, all of the resulting elements are not rendered in cells. For example, if I enter the formula:
={{1,2,3}, {4,5,6}}
the values rendered in spreadsheet cells are 1,4,5,6. Any ideas about why this is happening, or alternatives? My broader problem is to accumulate rows from separate sheets into another sheet - I can do that via
={ImportRange(...), ImportRange(...)}
but the same problem is apparent (missing the second element and beyond from the first array).
Edit (2 Oct 2014)
I just happened upon this when someone upvoted. The information below is obsolete in the newest version of Sheets - you can now (have been able to for a few months) concatenate arrays inside embedded arrays. All the examples that I provided below will work, including the one I said "shouldn't work".
Embedded arrays in Google Sheets
An array of values may be populated by a single function using an embedded array. Each element in the embedded array (and this may be point of conjecture; it is more or less just my opinion) represents the value that will be populated in contiguous cells in the sheet. Semi-colons are row delimiters; commas (or backslashes in locales that use a comma for a decimal separator) are column delimiters. So this will successfully create a two-row, three-column array (all of the following examples assume a locale supporting comma column delimiters):
={1,2,3;4,5,6}
Embedded arrays within embedded arrays
As each element in an embedded array represents a cell in the spreadsheet, I think it is reasonable to assume that one should be able to populate a cell with another embedded array, as long as it does not overwrite other elements in the outer embedded array. So IMO something like this should (see point 3) be successful:
={{1;2;3},{4;5;6}}
However something like this shouldn't work (again IMO), as the second and third elements of the first embedded array would be "overwriting" the second embedded array:
={{1,2,3},{4,5,6}}
There is a bug associated with the first embedded array inside an embedded array
As +Jason pointed out, something like ={{1;2;3},{4;5;6},{7;8;9}} doesn't work in that the first embedded array only populates one element (but every other column is populated correctly). It is also interesting that that one element is auto-converted to a text string. This is (unfortunately) a long standing bug in Google Sheets. The same thing occurs when you attempt to invoke the SPLIT() function on an array (every element in the array is split successfully except for the first one).
I don't think embedded arrays within embedded arrays will help with your broader problem anyway
Embedded arrays can't really be used to append one array on to end of another anyway (due to the "overwriting" effect), and there is no native function that can do it directly. The VMERGE function which you can obtain via the Script gallery (credit to +ahab) will work out of the box:
=VMERGE(ImportRange(...);ImportRange(...);...)
or you can use native functions to do some string manipulation to achieve this. For example, for one-dimensional arrays:
=ArrayFormula(TRANSPOSE(SPLIT(CONCATENATE(ImportRange("key1";"A1:A10")&CHAR(9);ImportRange("key2";"A1:A10")&CHAR(9));CHAR(9))))
but as well as being clunky and not very readable, this type of formula can be very expensive performance-wise for large data sets (I would tend to recommend the VMERGE custom function option in preference).
It is possible to make a union in Google Spreadsheet very easily. For example:
={'Sheet1'!A2:A;'Sheet2'!A2:A;'Sheet3'!A2:A}
See more info in Google Docs Help: Using arrays in Google Sheets
Assuming you have 3 arrays A2:B7, D4:E12, and F2:G230 with the same number of columns but different lengths (often the case if you have the same table of data split into different tabs for each period), I think the easiest way is something like this:
=TRANSPOSE({TRANSPOSE(A2:B7), TRANSPOSE(D4:E12), TRANSPOSE(F2:G230)})

Matlab access array element in one line

a = 0:99
s = size(a)
disp(s(2))
Can the last two lines be written as one? In other languages I am able to do f(x)[i], but Matlab seems to complain.
In this specific case where you are using the size function, you can add an additional argument to specify the dimension you want the size of, allowing you to easily do this in one line:
disp(size(a, 2)); % Displays the size of the second dimension
In the more general case of accessing an array element without having to store it in a local variable first, things get a little more complicated, since MATLAB doesn't have the same kind of indexing shorthand you would find in other languages. Octave, for example, would allow you to do disp(size(a)(2)).
It is possible to collapse those two lines in one single statement and achieve a sort of f(x)[i] thanks to the functional form of the indexing operator: subsref.
disp(subsref(size(a), struct('type', '()', 'subs', {{2}})))

How can I printf first in columns then in lines?

maybe this question seems stupid... I would like to fprintf a dataset formatted in rows and columns. I know the procedure so far
for(i=0;i<number_of_rows;i++)
{
for(j=0;j<number_of_columns;j++)
fprintf(file,"%g\t",array[i][j]);
fprintf(file,"\n");
}
What essentially does this code is to fill up first the rows and then the columns. I have datasets that are created by columns. Thus, I want to fill up every column before I pass to the next one. I don't know before the runtime the length of the output data in order to make a proper 2D array. And I need to print out first a whole column, then the other. How can I do this?
And I need to print out first a whole column, then the other. How can I do this?
That would involve appending to a previously printed line. And, as you may know, adding content into a file involves rewriting the entire rest of the file. You can probably guess that would be incredibly inefficient and also complicated to implement.
I don't know before the runtime the length of the output data in order to make a proper 2D array
If your problem is the length of the data, then I assume that by proper 2D array you mean that you intend to pad each cell of a column to be the same width.
In that case, I recommend not to waste time on the idea of writing column first. Instead, calculate the widths at runtime. First sprintf into a matrix of strings and calculate the length of each cell. Then print the matrix of strings using the calculated lengths.

Appending google spreadsheet arrays

When I append arrays in google spreadsheets, all of the resulting elements are not rendered in cells. For example, if I enter the formula:
={{1,2,3}, {4,5,6}}
the values rendered in spreadsheet cells are 1,4,5,6. Any ideas about why this is happening, or alternatives? My broader problem is to accumulate rows from separate sheets into another sheet - I can do that via
={ImportRange(...), ImportRange(...)}
but the same problem is apparent (missing the second element and beyond from the first array).
Edit (2 Oct 2014)
I just happened upon this when someone upvoted. The information below is obsolete in the newest version of Sheets - you can now (have been able to for a few months) concatenate arrays inside embedded arrays. All the examples that I provided below will work, including the one I said "shouldn't work".
Embedded arrays in Google Sheets
An array of values may be populated by a single function using an embedded array. Each element in the embedded array (and this may be point of conjecture; it is more or less just my opinion) represents the value that will be populated in contiguous cells in the sheet. Semi-colons are row delimiters; commas (or backslashes in locales that use a comma for a decimal separator) are column delimiters. So this will successfully create a two-row, three-column array (all of the following examples assume a locale supporting comma column delimiters):
={1,2,3;4,5,6}
Embedded arrays within embedded arrays
As each element in an embedded array represents a cell in the spreadsheet, I think it is reasonable to assume that one should be able to populate a cell with another embedded array, as long as it does not overwrite other elements in the outer embedded array. So IMO something like this should (see point 3) be successful:
={{1;2;3},{4;5;6}}
However something like this shouldn't work (again IMO), as the second and third elements of the first embedded array would be "overwriting" the second embedded array:
={{1,2,3},{4,5,6}}
There is a bug associated with the first embedded array inside an embedded array
As +Jason pointed out, something like ={{1;2;3},{4;5;6},{7;8;9}} doesn't work in that the first embedded array only populates one element (but every other column is populated correctly). It is also interesting that that one element is auto-converted to a text string. This is (unfortunately) a long standing bug in Google Sheets. The same thing occurs when you attempt to invoke the SPLIT() function on an array (every element in the array is split successfully except for the first one).
I don't think embedded arrays within embedded arrays will help with your broader problem anyway
Embedded arrays can't really be used to append one array on to end of another anyway (due to the "overwriting" effect), and there is no native function that can do it directly. The VMERGE function which you can obtain via the Script gallery (credit to +ahab) will work out of the box:
=VMERGE(ImportRange(...);ImportRange(...);...)
or you can use native functions to do some string manipulation to achieve this. For example, for one-dimensional arrays:
=ArrayFormula(TRANSPOSE(SPLIT(CONCATENATE(ImportRange("key1";"A1:A10")&CHAR(9);ImportRange("key2";"A1:A10")&CHAR(9));CHAR(9))))
but as well as being clunky and not very readable, this type of formula can be very expensive performance-wise for large data sets (I would tend to recommend the VMERGE custom function option in preference).
It is possible to make a union in Google Spreadsheet very easily. For example:
={'Sheet1'!A2:A;'Sheet2'!A2:A;'Sheet3'!A2:A}
See more info in Google Docs Help: Using arrays in Google Sheets
Assuming you have 3 arrays A2:B7, D4:E12, and F2:G230 with the same number of columns but different lengths (often the case if you have the same table of data split into different tabs for each period), I think the easiest way is something like this:
=TRANSPOSE({TRANSPOSE(A2:B7), TRANSPOSE(D4:E12), TRANSPOSE(F2:G230)})

What is the best way to count the number of times a value occurs in an array?

I have been given an assignment to write a program that reads in a number of assignment marks from a text file into an array, and then counts how many marks there are within particular brackets, i.e. 40-49, 50-59 etc. A value of -1 in the text file means that the assignment was not handed in, and a value of 0 means that the assignment was so bad that it was ungraded.
I could do this easily using a couple of for loops, and then using if statements to check the values whilst incrementing appropriate integers to count the number of occurences, but in order to get higher marks I need to implement the program in a "better" way. What would be a better, more efficient way to do this? I'm not looking for code right now, just simply "This is what you should do". I've tried to think of different ways to do it, but none of them seem to be better, and I feel as if I'm just trying to make it complicated for the sake of it.
I tried using the 2D array that the values are stored in as a parameter of a function, and then using the function to print out the number of occurences of the particular values, but I couldn't get this to compile as my syntax was wrong for using a 2D array as a parameter, and I'm not too sure about how to do this.
Any help would be appreciated, thanks.
Why do you need a couple for loops? one is enough.
Create an array of size 10 where array[0] is marks between 0-9, array[1] is marks between 10-19, etc. When you see a number, put it in the appropriate array bucket using integer division, e.g. array[(int)mark/10]++. when you finish the array will contain the count of the number of marks in each bucket.
As food for thought, if this is a school assignment, you might want to apply other things you have learned in the course.
Did you learn sorting yet? Maybe you could sort the list first so that you are not iterating over the array several times. You can just go over it once, grab all the -1's, and spit out how many you have, then grab all the ones in the next bracket and so on.
edit: that is of course, assuming that you are using a 1d array.

Resources