1D Array into 2D array (vb) - arrays

I have split the 1d array and i need convert it into a 2d array. The array consists of numbers (scores) and names as results of a numerical test.
Dim results1 As String = File.ReadAllText("Z:\scores class 1.txt")
Dim array = Split(results1, " ")
For i As Integer = 0 To array.Length - 1
Console.WriteLine(array(i))
Next
Console.WriteLine("Would you like these to be sorted? Press 1 for yes, 2 for no")
If Console.ReadLine = 1 Then
' do some stuff
ElseIf Console.ReadLine = 2 Then
' do some stuff
End If
Console.ReadLine()
That is my current code, what do i need to add?
Thanks for any help.

Converting 1D to 2D is possible when you have contigious key/value present to make it as index of array but in your case it is neither. So better option will be to use HashMap/HashTable in general. As per your requirement instead of using 2D array to represent name: value pair you should use a HashMap .
As per your statement in commnets you have an 1D array which holds name:value
i.e
String arr [] = { "jack", "23", "mat","45", "mike","56" }
You can better represent it as a HashMap .
HashMap<String,Integer> hm = new HashMap<String,Integer>();
hm.add("jack",23); // it will add score of 23 to name jack i.e "jack" : 23
hm.add("mat",45);
hm.add("mike",56);
Now you can easily manipulate any name:value pair
e.g. To get marks scored by "mat" just write hm.get("mat")
It will output the marks associated with mat i.e 45.

Dim array2((array.Length / 2) - 1, 1) As String
For i As Integer = 0 To (array.Length - 1) / 2 Step 1
array2(i, 0) = array(i * 2)
array2(i, 1) = array((i + 1) * 2 - 1)
Next
This creates a two dimensional array with the values from the 1d array.

Related

VBA Change a 1 column array to a one dimensional array

I am loading an array from a table.
aryNonE = ActiveSheet.Range("AA1:AA" & lRowNonE - 1)
test = Array("Bob Smith", "John Davies"...)
Want to use Filter but get type mismatch on aryNonE.
test works fine
[Debug shows1
How do I get aryNonE to look like test??
Thanks
Try this way, please:
Sub test2DTo1DArray()
Dim aryNonE, lRowNonE As Long
lRowNonE = 10
aryNonE = ActiveSheet.Range("AA1:AA" & lRowNonE - 1) '2D array
aryNonE = Application.Transpose(Application.Index(aryNonE, 0, 1)) '1D array
'You can test it in this way:
Debug.Print Join(aryNonE, ",")
End Sub
In this way, it can be used to filter using an array like Criteria1...
But, if the values in the 2D array are numbers, since the Criteria array must keep only strings, the range where the array is extracted from, must preliminarily be formatted as text.

Filter MATLAB non-numerical array data based on criteria

Two questions, one fairly simple question (at least it seems it should be simple) and one that may take a bit more work. Feel free to contribute to either or both.
First, I'd like to create a string array based off of an existing string array based on a criteria. Take for example a similar operation with a double array:
>> nums = [ 1 2 1 2]
nums =
1 2 1 2
>> big_nums = (nums == 2) .* nums
big_nums =
0 2 0 2
I'd like to do something similar with a string array, however I don't know what function to use:
>> sizes = ["XL" "L" "XL" "L"]
sizes =
1×4 string array
"XL" "L" "XL" "L"
>> large_sizes = (sizes == "L") .* sizes
Undefined operator '.*' for input arguments of type 'string'.
I'd like the output to be
large_sizes =
1×4 string array
"" "L" "" "L"
Second question. Suppose I have a 2 dimensional cell array. I'd like to filter data based on criteria:
>> data = {"winter", 1; "spring", 2; "summer", 3; "fall", 4}
data =
4×2 cell array
["winter"] [1]
["spring"] [2]
["summer"] [3]
["fall" ] [4]
>> nice_weather = ( (data(1,:) == "fall") + (data(1,:) == "spring") ) .* data
Error using ==
Cell must be a cell array of character vectors.
I'd like a code that results in one of two arrays:
nice_weather =
4×2 cell array
[""] [1]
["spring"] [2]
[""] [3]
["fall"] [4]
----- OR -----
nice_weather =
2×2 cell array
["spring"] [2]
["fall"] [4]
For this question, I am also open to separating data into multiple arrays (for example, one array for strings and one array for numbers).
Thanks!
This solution uses the strcmpi function from MATLAB (no toolbox required) to compare two strings (insensitive to the case).
1D Cell Array:
sizes = {'XL' 'L' 'XL' 'L'}; % Changed " to ' & used cell array
idx = strcmpi(sizes,'L'); % Logical index
sizelist = {sizes{idx}}
Or you could try something like
sizes(~idx) = {"" ""} % manual just for example
For this to automatically adjust the number of blanks "", you could use repmat like this
sizes(~idx) = repmat({""},1,sum(~idx))
Output:
sizes = 1×4 cell array
{[""]} {'L'} {[""]} {'L'}
2D Cell Array:
data = {'winter', 1; 'spring', 2; 'summer', 3; 'fall', 4}; % Changed " to '
nicemo1 = 'spring';
nicemo2 = 'fall';
idx = strcmpi(data(:,1),nicemo1) | strcmp(data(:,1),nicemo2); % Obtain logical index
data(idx,:)
Output:
ans = 2×2 cell array
{'spring'} {[2]}
{'fall' } {[4]}
Tested with MATLAB R2018b.
Also beware variables like sizes as dropping a letter masks a useful function, size.

defining array from worksheet not working in filter () lines with type mismatch error

I'm using secondarray as range of cells in a worksheet (Ex. "1", "2") to exclude them as autofilter list that I'm defining in the below function in "filtercriteria".
I get "type mismatch" error in the filter (secondarray) line for some reason, but I works flawlessly when I define an array using a list of items instead. For example, if I use below line to define secondarray instead.
secondarray = ("1", "2")
I've researched similar postings and wasn't lucky, can someone help with this instance?
Thanks,
Dim secondArray As Variant
secondArray = Range("L76:M76").Value
c = 0
k = 0
count = 0
rowNumb = Worksheets("List").Range(Worksheets("List").Range("L5"), Worksheets("List").Range("L5").End(xlDown)).Rows.count
For L = 1 To rowNumb
c = Worksheets("List").Range("L5").Offset(L)
If c <> k Then
'check the current activity type against the array of types we don’t want. If it isn’t in the array we add it to an array that will be used as the filter criteria
If UBound(Filter(secondArray, c)) = -1 Then
ReDim Preserve filterCriteria(0 To count)
filterCriteria(count) = c
count = count + 1
End If
k = c
End If
Next
It isn't working because filter function takes a One-dimensional array of strings to be searched for its sourcearray argument.
When you read in a range from the sheet you automatically get a 2d array as opposed to the 1D you have when assigning from a list.
Find a way to use a 1D array to pass in
For example, as your data is coming from 1 row then slice the array by row
UBound(Filter(Application.WorksheetFunction.Index(secondArray, 1, 0), c)) = -1
You may need to find the right method for you.
Another method is given here.

Get indices of string occurrences in cell-array

I have a cell array that contains a long list of strings. Most of the strings are in duplicates. I need the indices of instances of a string within the cell array.
I tried the following:
[bool,ind] = ismember(string,var);
Which consistently returns scalar ind while there are clearly more than one index for which the contents in the cell array matches string.
How can I have a list of indices that points to the locations in the cell array that contains string?
As an alternative to Divakar's comment, you could use strcmp. This works even if some cell doesn't contain a string:
>> strcmp('aaa', {'aaa', 'bb', 'aaa', 'c', 25, [1 2 3]})
ans =
1 0 1 0 0 0
Alternatively, you can ID each string and thus have representative numeric arrays corresponding to the input cell array and string. For IDing, you can use unique and then use find as you would with numeric arrays. Here's how you can achieve that -
var_ext = [var string]
[~,~,idx] = unique(var_ext)
out = find(idx(1:end-1)==idx(end))
Breakdown of the code:
var_ext = [var string]: Concatenate everything (string and var) into a single cell array, with the string ending up at the end (last element) of it.
[~,~,idx] = unique(var_ext): ID everything in that concatenated cell array.
find(idx(1:end-1)==idx(end)): idx(1:end-1) represents the numeric IDs for the cell array elements and idx(end) would be the ID for the string. Compare these IDs and use find to pick up the matching indices to give us the final output.
Sample run -
Inputs:
var = {'er','meh','nop','meh','ya','meh'}
string = 'meh'
Output:
out =
2
4
6
regexp would solve this problem better and the easy way.
string = ['my' 'bat' 'my' 'ball' 'my' 'score']
expression = ['my']
regexp(string,expresssion)
ans = 1 6 12

declaring two-dimensional array

I have a couple of college assignments I am having trouble with. Really I am just confused about one thing regarding an array. I need to declare a three column, 5 row array. The first two columns are integers and the third column is the letter grade. So I am very confused about declaring the data type since they are different. This is my first go-around with arrays, so please excuse my ignorance. Here is an what my array is supposed to look like.
Column 1 {0,300,350,400,450}
Column 2 {299,349,399,449,500}
Column 3 {F,D,C,B,A}
(It's a grading app)
I can solve the rest of the problem myself, I am just confused about this array portion. So my question is strictly about how to declare such an array. It say's to use a two-dimensional array which only confuses me more since there are three columns. Thank you!
2-dimensional array is correct. First index is column, second index is row.
Dim strData(,) As String 'Use String variable type, even for the numbers
Dim intRowCount As Integer = 5
Dim intColumnCount As Integer = 3
ReDim strData(intColumnCount - 1, intRowCount - 1) 'subtract 1 because array indices are 0-based. Column 0 = Range start, Column 1 = Range End, Column 2 = Grade
'first row
strData(0, 0) = "0" 'Range start
strData(1, 0) = "299" 'Range end
strData(2, 0) = "F" 'Grade
'second row
strData(0, 1) = "300"
strData(1, 1) = "349"
strData(2, 1) = "D"
'third row
strData(0, 2) = "350"
strData(1, 2) = "399"
strData(2, 2) = "C"
'fourth row
strData(0, 3) = "400"
strData(1, 3) = "449"
strData(2, 3) = "B"
'fifth row
strData(0, 4) = "450"
strData(1, 4) = "500"
strData(2, 4) = "A"
'Add a row
intRowCount = intRowCount + 1
ReDim Preserve strData(intColumnCount - 1, intRowCount - 1)
'sixth row
strData(0, 5) = "501"
strData(1, 5) = "600"
strData(2, 5) = "A+"
Note that Redim Preserve can only change the last index in the array, which is why we store in (column, row) order rather than the more traditional (row, column) order.
There are a couple of ways to approach this. One is to declare the array as Object type, and they assign integers or strings to the appropriate element. Some don't consider this socially acceptable, though, because it can lead to code that's difficult to debug.
You could also use a String type for a two dimensional array and save the integers in string variables. This is also not normally done because of the conversion necessary for numeric comparisons and computation.
Another approach is to use a structure or class that contains the three values, and make an array of that.
For example,
Structure Item
Dim col1 as integer
Dim col2 as integer
Dim col3 as string
End Structure
Dim itemList(20) as Item
itemList(4).col1 = 23
itemList(4).col2 = 45
itemList(4).col3 = "somestring"

Resources