A Introduction to Programming Using Visual Basic 2010 (Eighth Edition) David I. Schneider Instructor Name:Liang Jiankun E-Mail:teacherljk@163.com Phone: 23986531 Office: Computer Center Chapter 6 – Arrays 6.1 Creating and Accessing Arrays 6.2 Using LINQ with Arrays 6.3 Arrays of Structures 6.4 Two-Dimensional Arrays 6.1 Creating and Accessing Arrays • • • • • • • Declaring an Array Variable The Load Event Procedure Implicit Array Sizing Calculating an Array Value with a Loop The ReDim Statement Flag Variables For Each Loops 6.1 Creating and Accessing Arrays (continued) • • • • • Passing an Array to a Procedure User-Defined Array-Valued Functions Searching for an Element in an Array Copying an Array Split Method and Join Function Simple Variable vs Array • A variable (or simple variable) is a name to which Visual Basic can assign a single value • An array variable is a collection of simple variables of the same type with same name to which Visual Basic can efficiently assign a list of values. Example advantage of array Suppose you want to evaluate the exam grades for 10 students and to display the scores which are above the average Dim Score1, Score2, Score3, Score4, Score5 As Integer Dim Score6, Score7, Score8, Score9, Score10 As Integer Dim Sum As Integer, Average As Double Score1 = CInt(InputBox("Please input a new score")) Score2 = CInt(InputBox("Please input a new score")) Score3 = CInt(InputBox("Please input a new score")) Score4 = CInt(InputBox("Please input a new score")) Score5 = CInt(InputBox("Please input a new score")) Score6 = CInt(InputBox("Please input a new score")) Score7 = CInt(InputBox("Please input a new score")) Score8 = CInt(InputBox("Please input a new score")) Score9 = CInt(InputBox("Please input a new score")) Score10 = CInt(InputBox("Please input a new score")) Sum = Score1 + Score2 + Score3 + Score4 + Score5 + _ Score6 + Score7 + Score8 + Score9 + Score10 Example Average = Sum / 10 txtAve.Text = CStr(Average) If Score1 > Average Then txtAbove.Text &= Score1 & " End If If Score2 > Average Then txtAbove.Text &= Score2 & " End If If Score3 > Average Then txtAbove.Text &= Score3 & " End If If Score4 > Average Then txtAbove.Text &= Score4 & " End If If Score5 > Average Then txtAbove.Text &= Score5 & " End If " " " " " If Score6 > Average Then txtAbove.Text &= Score6 & " " End If If Score7 > Average Then txtAbove.Text &= Score7 & " " End If If Score8 > Average Then txtAbove.Text &= Score8 & " " End If If Score9 > Average Then txtAbove.Text &= Score9 & " " End If If Score10 > Average Then txtAbove.Text &= Score10 & " " End If . Example Realize with Repetition-structure and simple variable Dim Score As Integer Dim Sum As Integer, Average As Double For i = 1 To 10 Score = CInt(InputBox("Please input the " & i & " th score")) Sum += Score Next The 10 scores must be input twice, because a simple variable only store a single value. Average = Sum / 10 txtAve.Text = CStr(Average) For i = 1 To 10 Score = CInt(InputBox("Please input the " & i & " th score")) If Score > Average Then txtAbove.Text &= Score & " " End If Next Example No matter how many scores are there, the program structure is the same. Realize with array Dim Score(9) As Integer Dim Sum As Integer, Average As Double For i = 0 To 9 Score(i) = CInt(InputBox("Please input the " & i & " th score ")) Sum += Score(i) Next Average = Sum / 10 txtAve.Text = CStr(Average) For i = 0 To 9 If Score(i) > Average Then txtAbove.Text &= Score(i) & " " End If Next Array Terminology Syntax: Dim arrayName(n) As DataType • 0 is the lower bound of the array • n is the upper bound of the array–the last available subscript in this array • The number of elements, n + 1, is the size of the array. Putting Values into an Array score(0) = 10 subscript Read: "score sub zero equals ten" Which means that the number 10 is being stored at the first location in the array called score because all arrays begin counting at 0 In other words, score(0) is the first element of array score(). Example 1 Private Sub btnWho_Click(...) Handles btnWhoWon.Click Dim teamNames(3) As String Dim n As Integer teamNames(0) = "Packers" teamNames(1) = "Packers" teamNames(2) = "Jets" teamNames(3) = "Chiefs" n = CInt(txtNumber.Text) txtWinner.Text = teamName(n - 1) End Sub Super Bowl 美国橄榄球超级杯大赛 Load Event Procedure Occurs as the Form loads in memory Private Sub frmName_Load(...) Handles MyBase.Load The keyword MyBase refers to the form being loaded. This event procedure is a good place to assign values to an array. Example 2: Form-Load procedure The array can’t declared within any event procedure, It must be Class-Scope. Dim teamNames(3) As String Private Sub frmBowl_Load(...) Handles MyBase.Load teamNames(0) = "Packers" teamNames(1) = "Packers" teamNames(2) = "Jets" teamNames(3) = "Chiefs" End Sub Private Sub btnWhoWon_Click(...) Handles btnWhoWon.Click Dim n As Integer n = CInt(txtNumber.Text) txtWinner.Text = teamNames(n - 1) End Sub Initializing Arrays Arrays may be initialized when created: Dim arrayName() As DataType={value0,value1,value2,...,valueN} declares an array having upper bound N and assigns value0 to arrayName(0), value1 to arrayName(1), ..., and valueN to arrayName(N). Example: Dim teamNames() As String={"Packers","Packers","Jets","Chiefs"} Dim Score() As Integer={10, 20, 30, 40, 50, 60, 70, 80, 90, 100} 圆括号:parenthesis 大括号:curly bracket 逗号:comma 引号:quotation mark Example 2: Simplified writing You can’t specify the subscript here, the size of the array is decided by the following list Dim teamNames(3) As String Private Sub frmBowl_Load(...) Handles MyBase.Load Dim teamNames() As String={"Packers","Packers","Jets","Chiefs"} End Sub Private Sub btnWhoWon_Click(...) Handles btnWhoWon.Click Dim n As Integer = CInt(txtNumber.Text) txtWinner.Text = teamNames(n - 1) End Sub Text Files Some times text file is used to offer the initial values of array. Such as Presidents.txt, States.txt etc. • Can be created, viewed, and managed by word processors or by the Visual Basic IDE • Have the extension txt • Normally placed in the bin\Debug folder in the Solution Explorer. Using a Text File to Populate a String Array • Assume the text file named theNamesOfTheFirstSixPresidents.txt lies in the bin\Debug folder. • The text file can be used to fill string array with the statement Dim PNames() As String =IO.File.ReadAllLines("theNamesOfTheFirstSixPresidents.txt") • The array PNames will have size 6 and upper bound 5. Array Methods Dim PNames() As String =IO.File.ReadAllLines("theNamesOfTheFirstSixPresidents.txt") Method Name Value Value in this case arrayName.Count number of elements arrayName.Max highest value(不区分大小写数字比字母小) Thomas Jefferson arrayName.Min lowest value(不区分大小写数字比字母小) George Washington arrayName.First first element George Washington arrayName.Last last element John Q. Adams arrayName.Average Average value(需为数值型数组) arrayName.Sum The sum of the elements(需为数值型数组) 6 Array Methods (continued) • The upper bound of arrayName is arrayName.Count – 1 • arrayName.First is the same as arrayName(0) Populating a Numeric Array with a Text File If you want to evaluate the elements value numerically (such as average, sum etc.), you should change the array from string to numeric type. Dim FinalScores() As String=IO.File.ReadAllLines("Scores.txt") Dim Scores(FinalScores.Count-1) As Integer For i As Integer = 0 To FinalScores.Count-1 Scores(i) = CInt(FinalScores(i)) lstOutput.Items.Add(Scores(i)) Next lstOutput.Items.Add("The highest value is " & Scores.Max) lstOutput.Items.Add("The lowest value is " & Scores.Min) lstOutput.Items.Add("The average is " & Scores.Average) lstOutput.Items.Add("The sum is " & Scores.Sum) Using Loops Instead of Methods Dim ages() As Integer = {55, 56, 61, 52, 69, 64, 46, 54, 47} Dim max As Integer = ages(0) For i = 1 To ages.Count - 1 If ages(i) > max Then max = ages(i) End If Next txtOutput.Text = "Greatest age: " & max Output: Greatest age: 69 Using Loops Instead of Methods Cont. Another way, you may find the max element with the subscript Dim ages() As Integer = {55, 56, 61, 52, 69, 64, 46, 54, 47} Dim max As Integer = 0 For i = 1 To ages.Count - 1 If ages(i) > ages(max) Then max = i End If Next txtOutpxt = "Greatest age: " & ages(max) & ". It’s the " & max+1 & "th element" Output: Greatest age: 69. It’s the 5th element ReDim Statement You can’t change the type of an existing array, so there is no As DataType • The size of an array may be changed after it has been created with the following statement ReDim arrayName(m) • arrayName is the name of the already declared array • m is an Integer literal, variable, or expression • the upper bound of the array is changed to m. Preserve Keyword ReDim arrayName(m) • resets all values to their default.This can be prevented with the keyword Preserve ReDim Preserve arrayName(m) • resizes the array and retains as many values as possible. Flag Variables Flag variables have type Boolean. They are used when looping through an array. It may provide information to be used after loop terminates. Or, allows for the early termination of the loop. Dim Score() As String Private Sub Button1_Click(…) Handles Button1.Click Score = IO.File.ReadAllLines("scores.txt") For i = 0 To Score.Count - 1 lstoutput.Items.Add(Score(i)) Dim n As String = TextBox1.Text Dim Found As Boolean = False Next For i = 0 To Score.Count - 1 End Sub If Score(i) = n Then Found = True Exit For End If Next If Found = True Then MessageBox.Show(n & " is found.") Else MessageBox.Show("There is no " & n & " in the array.") End If For Each Loops For i As Integer = 0 To ages.Count - 1 If ages(i) > max Then max = ages(i) End If Next The Looping variable can be any name can be replaced with For Each x As Integer In ages If x > max Then max = x End If Next For i = 0 To Score.Count - 1 If Score(i) = n Then Found = True Exit For End If Next can be replaced with For each Mark as string In Score If mark = n Then Found = True Exit For End If Next Passing an Array Element A single element of an array can be passed to a procedure just like any ordinary numeric or string variable. Private Sub btnDisplay_Click(...) Handles btnDisplay.Click Dim num(20) As Integer num(5) = 10 lstOutput.Items.Add(Triple(num(5))) End Sub Function Triple(ByVal x As Integer) As Integer Return 3 * x End Function The header of the Function procedure uses the name with an empty set of parentheses Passing Arrays to Procedures cont. Function Range(ByVal x() As Integer) As Integer Dim Large, Small, N As Integer Large = x.Max Small = x.Min N = Large - Small Return N End Function The calling statement uses the name of the array without parentheses. Private Sub btnCalculate_Click(...) Handles btnCalculate.Click Dim ages() As Integer = {55, 56, 61, 52, 69, 64, 46, 54, 47} txtOutput.Text = “The range of the array is " & Range(ages) End Sub User-Defined Array-Valued Functions Headers have the form Function FunctionName(ByVal var1 As Type1, ByVal var2 As Type2, ...) As DataType() Function Prime(ByVal x() As Integer) As Boolean() Dim JG(x.Count - 1) As Boolean ‘记录结果 For i = 0 To x.Count - 1 Dim flag As Boolean = True For j = 2 To x(i) – 1 此函数的返回值为一个布 If x(i) Mod j = 0 Then 尔型的数组,每个元素的 flag = False Exit For 值就是数组x()对应元素的 End If 素数判断结果 Next j If flag Then JG(i) = True Else JG(i) = False End If Next i Return JG End Function Searching for an Element in an Array numVar = Array.IndexOf(arrayName, value) • assigns to numVar the index of the first occurrence of value in arrayName. • Or assigns -1 if the value is not found. Dim colors() As String = IO.File.ReadAllLines("Colors.txt") Private Sub btnDetermine_Click(…) Handles btnDetermine.Click Dim color As String = txtColor.Text If Existing(color, colors) Then txtOutcome.Text = color & " is a crayola color." Else txtOutcome.Text = color & " is not a crayola color." End If End Sub Function Existing(ByVal x As String, ByVal y() As String) As Boolean If Array.IndexOf(y, x) = -1 Then Return False Else Return True End If End Function Copying an Array arrayOne = arrayTwo makes arrayOne an exact duplicate of arrayTwo If only arrayOne and arrayTwo have been declared with the same data type, no matter what is the size of arrayOne . They share the same location in memory. Copying an Array Cont. Dim a() As Integer = {10, 20, 30, 40, 50} Dim b() As Integer b = a Dim a() As Integer = {10, 20, 30, 40, 50} As Integer For i =Dim 0 Tob(4) 4 b = a Dim a() As Integer = {10, 20, 30, 40, 50} ListBox1.Items.Add(b(i)) Dim b(2) As Integer For i = 0 To 4 Next b = a Dim a() As Integer = {10, 20, 30, 40, 50} ListBox1.Items.Add(b(i)) Dim b(8) As Integer ListBox1.Items.Add("Ubound(b)=" & b.Count - 1) For i = 0 To 4 Next b=a ListBox1.Items.Add(b(i)) ListBox1.Items.Add("Ubound(b)=" & b.Count - 1) For i = 0 To 4 Next ListBox1.Items.Add(b(i)) & b.Count - 1) ListBox1.Items.Add("Ubound(b)=" Next ListBox1.Items.Add("Ubound(b)=" & b.Count - 1) . 结论:只要数组a和b都是一维数组且类型相同, 无论数组b原来的下标如何,都会被重新定义为和a一样! Copying an Array Cont. Dim a() As Integer = {10, 20, 30, 40, 50} Dim b() As Integer Dim a() As Integer = {10, 20, 30, 40, 50} b=a Dim b(4) As Integer For i = 0 To 4 For i = 0 To 4 b(i) = b(i) / 2 b(i) = a(i) Next Next For i = 0 To 4 For i = 0 To 4 b(i) = b(i) / 2 ListBox1.Items.Add(a(i)) Next Next For i = 0 To 4 结论:数组a和b经过直接复制操 ListBox1.Items.Add(a(i)) 作后,它们在内存中指向同一位 Next 置(同一个数组的两个不同名称) 结论:数组a和b经过逐元素赋值后,它们 只有初始值相同,其它无任何联系。 Split Method • Facilitates working with text files. • Split can convert a string containing commaseparated data into a string array. • The 0th element of the array contains the text preceding the first comma, the 1st element contains the text between the first and second commas, ..., and the last element contains the text following the last comma. Split Example For instance, suppose the string array employees has been declared without an upper bound, and the string variable line has the value “Bob,23.50,45”. Dim employees() as String employees = line.Split(","c) •sets the size of employees to 3 •sets employees(0) = “Bob” •sets employees(1) = “23.50” •sets employees(2) = “45” Split Comments employees = line.Split(","c) • In this example, the character comma is called the delimiter for the Split method, and the letter c specifies that the comma has data type Character instead of String • Any character can be used as a delimiter. If no character is specified, the space character will be used as the delimiter by default. Example Private Sub btnConvert_Click(...) Handles btnConvert.Click Dim stateData(), line As String line = "California,1850,Sacramento,Eureka" stateData = line.Split(","c) For Each entry As String In stateData lstOutput.Items.Add(entry) Next End Sub California 1850 Sacramento Eureka Join Function The reverse of the Split method is the Join function. Join concatenates the elements of a string array into a string containing the elements separated by a specified delimiter. Dim numbers() As String = {"One", "Two", "Three", "Four"} Dim s As String s = Join(numbers, "-") txtOutput.Text = s Output: One-Two-Three-Four Out of Range Error The following code references an array element that doesn't exist. This will cause an error. Comments and Exercises Comments6.1 P206 Exercises6.1 P207 6.2 Using LINQ with Arrays • • • • • • • • LINQ Queries The Distinct Operator The ToArray Method Use of Function Procedures in Queries The Let Operator The OrderBy Operator The DataSource Property Binary Search What is LINQ? • LINQ stands for Language INtegrated Query • A query is a request for information Note: Option Infer must be set to ON in order to use LINQ LINQ Query Code of the form range variable Dim queryName = From var In arrayName source data Where [condition on var] filter data过滤数据 Select var Project data投影数据 query operators • declares the variable queryName and assigns to it a sequence of the values from arrayName that satisfy the stated condition • The values in the sequence can be converted to an array, displayed in a list box, or written to a text file Example 1 'States.txt contains names of the 50 states Dim states() As String = IO.File.ReadAllLines("States.txt") Dim stateQuery = From s In states Where s.Length = 5 Select s For Each s As String In stateQuery lstStates.Items.Add(s) Next lstStates.Items.Add(stateQuery.Count) lstStates.Items.Add(stateQuery.Min) lstStates.Items.Add(stateQuery(1)) Maine缅因州, Texas德克萨斯州, Idaho爱达荷州 Example 2 Dim nums() As Integer = {7, 11, 12, 14, 15, 16, 18, 21, 30} Dim numQuery = From n In nums Where n > 10 And n < 20 And n Mod 2 = 0 Select n For Each m As Integer In numQuery lstBox.Items.Add(m) Next lstBox.Items.Add("") lstBox.Items.Add("Largest number: " & numQuery.Max) lstBox.Items.Add("Second number: " & numQuery(1)) lstBox.Items.Add("Sum of numbers: " & numQuery.Sum) Another Variation of Example 2 Dim S() As Integer = {5, 12, 8, 7, 11, 5, 8} Dim numQuery = From num In S Where num < 10 Select num * num changed For Each X As Integer In numQuery lstBox.Items.Add(X) Next Output: 25, 64, 49, 25, 64 Distinct Operator The sequence created with a LINQ query might contain duplicate elements. Duplicates can be eliminated with key word Distinct. Dim S() As Integer = {5, 8, 7, 5, 8} Dim numQuery = From num In S Select num Distinct There is no Where clause. It means select all the elements For Each X As Integer In numQuery lstBox.Items.Add(X) Next Output: 5, 8, 7 ToArray Method Also the sequence returned by a LINQ query has many of the features of an array(it has Max, Min, Sum, Average, Count, First, Last methods and subscripts just like an array), but the query is not an array variable because it hasn’t datatype and its values can’t be altered with assignment statements. The ToArray method can convert it to an array variable Dim nums() As Integer = {8, 12, 5, 7, 12, 5} Dim numQuery = From n In nums Where n < 10 Select n Distinct Dim Small() As Integer = numQuery.ToArray lstBox.Items.Clear() For i = 0 To Small.Count - 1 lstBox.Items.Add(Small(i)) Next RESULT:8, 5, 7. Function Procedures in Queries Function procedures may be used in Where and Select clauses Dim nums() As Integer = {5, 7, 8, 11, 12} Dim numQuery = From n In nums Where IsPrime(n) = True Select Triple(n) For Each m As Integer In numQuery lstBox.Items.Add(m) Next Let Operator A Let operator gives a name to an expression and makes queries easier to read Function LargestDivisor(ByVal x As Integer) As Integer Dim Max As Integer = 2 For i = 3 To x \ 2 If x Mod i = 0 Then Max = i End If Next Dim nums() As Integer = {15, 7, 39, 11, 21} Return Max Dim numQuery = From n In nums End Function Where IsPrime(n) = False 返回合数的最大质因子 Let ZuiDaYinZi = LargestDivisor(n) (不含1和自身) Select ZuiDaYinZi For Each m As Integer In numQuery lstBox.Items.Add(m) Next Order By Operator Order By Operator may sort string values into alphabetical order or sort numbers into numeric order either ascending or descending(Ascending by default) Dim nums() As Integer = {15, 17, 39, 5, 21, 13} Dim numQuery = From n In nums Where IsPrime(n) = True Order By n Descending Select n For Each m As Integer In numQuery lstBox.Items.Add(m) Next Example 5.. Dim stateQuery = From state In IO.File.ReadAllLines("States.txt") Order By state.Length, state Descending Select state For Each state As String In stateQuery lstOutput.Items.Add(state) Next 如果想只显示长度大于5的州名称,如何改写? 如果不需要过滤也不需要其它处理,只是为了对数 组进行排序,大可不必动用LINQ来进行Order By, Array.Sort(数据名)就可以实现对数组的简单升序排 序 。再进行一次Array.Reverse(数组名)就是降序。 DataSource Property The DataSource property fills a list box with the values returned by a query lstBox.DataSource = queryName.ToList The first entry will be highlighed by default. The highlighting can be eliminated with lstBox.SelectedItem = Nothing Dim stateQuery = From state In IO.File.ReadAllLines("States.txt") Order By state.Length, state Descending Select state lstOutput.DataSource = stateQuery.ToList 'lstOutput.SelectedItem = Nothing Binary Search A large array in ascending order is most efficiently searched with a binary search. The Binary Search method looks for a value in the array by first determining in which half of the array it lies. The other half is then ignored, and the search is narrowed to the retained half. A statement of the form numVar = Array.BinarySearch(arrayName, value) Assigns to numVar the index of an occurrence of the requested value in arrayName. If the value is not found, then a negative number is assigned to numVar. 注意:要想使用二分法查找,这个数组必须是升序的! Comments and Exercises Comments6.2 P217 Exercises6.2 P218 6.3 Arrays of Structures • • • • • • • Structures Arrays of Structures The DataGridView Control Searching an Array of Structures Using General Procedures with Structures Displaying and Comparing Structure Values Complex Structures (optional) Structures A structure is a group of different types of data, Also called a UDT (User Defined Type) Sample structure definition: Structure Nation Dim Name As String Dim Continent As String Dim Population As Double 'in millions Dim Area As Double 'in square miles End Structure Structure Definition Each subvariable in a structure is called a member To declare a variable of a structure type: Dim Country As Nation Each member is accessed via variableName.memberName For example: Country.Name = "China" Country.continent = "Asia" Example 1 Dim Country As Nation Country.Name = "China" Country.Continent = "Asia" Dim Country =As Nation Country.Population "1332.5" Dim line As String = "China,Asia,1332.5,3696100" Country.Area = "3696100" Dim data() As String = line.Split(","c) Country.Name = data(0) Country.Continent = data(1) Country.Population = CDbl(data(2)) Country.Area = CDbl(data(3)) Example 1 (continued) 'Display data in text boxes txtName.Text = country.name txtContinent.Text = country.continent txtPop.Text = FormatNumber(1000000*country.population,0) txtArea.Text = FormatNumber(country.area, 0) & " square miles" txtDensity.Text = FormatNumber(1000000*country.population / country.area) & " people per square mile" Text File: UN.txt The file UN.txt contains 192 countries each per line There are 4 fields (name, continent, pop in millions, area in square miles) for each country For Example: Canada,North America,32.9,3855000 France,Europe,63.5,211209 New Zealand,Australia/Oceania,4.18,103738 Australia,Australia/Oceania,21.9,2967909 China,Asia,1332.5,3696100 United States,North America,307.2,3794066 Example 3 Structure Nation Dim Name As String Dim Continent As String Dim Population As Double Dim Area As Double End Structure Dim nations(191) As Nation 'declare array Dim line, data() As String 'fill with UN.txt Dim countries() As String = IO.File.ReadAllLines("UN.txt") For i As Integer = 0 To 191 line = countries(i) 'Such as"China,Asia,1332.5,3696100" data = line.Split(","c) nations(i).name = data(0) nations(i).continent = data(1) nations(i).population = CDbl(data(2)) nations(i).area = CDbl(data(3)) Next Example 3: More Partial Code Dim selectedContinent As String = lstContinents.Text Dim query = From country In nations Where country.continent = selectedContinent Order By country.area Descending Select country.name For Each nation In query '此时query的结果都是国家的名称 lstCountries.Items.Add(nation) Next Structure College Structure College Dim name As String Dim state As String 'state abbreviation Dim yearFounded As Integer End Structure The file Colleges.txt contains the colleges founded before 1800 in US. There are 3 fields (name, state, year founded) in each line For Example: Harvard U.,MA,1636 Columbia U.,NY,1754 哈佛,马萨诸塞州(Massachusetts) 哥伦比亚大学,纽约州(New York) Example 4: Earliest Colleges Dim colleges() As College Private Sub frmColleges_Load(…) Handles MyBase.Load Dim schools() = IO.File.ReadAllLines("Colleges.txt") ReDim colleges(schools.Count - 1) Dim line As String Dim data() As String 'hold data for a single college For i As Integer = 0 To schools.Count - 1 line = schools(i) 'such as "Columbia U.,NY,1754" data = line.Split(","c) colleges(i).name = data(0) colleges(i).state = data(1) Structure College Dim name As String colleges(i).yearFounded = CInt(data(2)) Dim state As String Next Dim yearFounded As Integer End Sub End Structure Example 4: Earliest Colleges Cont. Private Sub btnDisplay_Click(….) Handles btnDisplay.Click Dim query = From C In colleges Where C.state = mtbState.Text.ToUpper Order By C.name Ascending Select C.name, C.yearFounded '提取出了其中的两列 lstColleges.Items.Clear() For Each institution In query lstColleges.Items.Add(institution.name & " " & institution.yearFounded) Next End Sub How to show information with several columns • Method 1: Output with ListBox normally • Method 2: Formatting output with zones • Method 3: With DataGridView control Formatting Output with Zones Method 2: • Use a fixed-width font such as Courier New • Divide the characters into zones with a format string Dim fmtStr As String = "{0, 15}{1, 10}{2, 8}" lstOutput.Items.Add(String.Format(fmtStr, data0, data1, data2)) Formatting Output with Zones (Display in tabular form) DataGridView Control Method 3: • • • • Useful when two or more pieces of information are to be displayed Lies in the Data group or All Windows Forms group of the Toolbox Displays a table with column headers AutoSizeColumnsMode property is used to set the width of column. DataSource Method When the Select clause of a query contains two or more items, the pair of statements DataGridView1.DataSource = queryName.ToList DataGridView1.CurrentCell = Nothing displays the items of data in a DataGridView control. (The second statement, which is optional, keeps all cells unhighlighted.) DataGridView Headers • By default the rows have blank headers and the column headers contain the names of the items in the Select clause column headers row headers DataGridView Headers (cont.) • Row headers can be removed by setting the RowHeadersVisible property of the DataGridView control to False. • A column header can be customized with a statement such as DataGridView1.Columns("Name").HeaderText = "University" DataGridView1.Columns("YearlyTuition").HeaderText = "Tuition" DataGridView1.Columns("YearFounded").HeaderText = "Year Founded" Searching an Array of Structures The Where clause of a query can be used to locate specific items(定位出那些具有某个特定值的项,例如某个州、某个成立年份等). If the query returns a sequence, a method such as First, Last, Max, Min and so on may be used to display a certain item. Example: Dim query = From institution In University Where institution.State = txtState.Text Order By institution.YearFounded Ascending Select institution txtName.Text = query.First.Name txtYear.Text = CStr(query.First.YearFounded) Comments and Exercises Comments6.3 P233 Exercises6.3 P234 6.4 Two-Dimensional Arrays • • • • Declaring a Two-Dimensional Array Variable Implicit Array Sizing and Initialization The ReDim Statement Filling a Two-Dimensional Array with a Text File Declaring a Two-Dimensional Array Variable • One-dimensional arrays store a list of items of the same type • Two-dimensional arrays store a table of items of the same type. • Consider the rows of the table as numbered 0, 1, 2,…, m and the columns numbered 0, 1, 2, …, n. Then the array is declared with Sized (指定大小的) two-dimensional array Dim arrayName(m, n) As DataType • The item in ith row, jth column write as arrayName(i,j) Implicit Array Sizing and Initialization A two dimensional array can be initialized when it is Unsized (未指明大小的) two-dimensional array declared as Dim arrayName(,) As DataType={{row0},{row1},...,{rowN}} • It declares a two-dimensional array where row0 consists of the entries in the top row of the corresponding table delimited by commas. For Example: Dim marks(,) As Integer={{50,20,80},{40,90,70},{60,10,30}} 50 20 80 40 90 70 60 10 30 Road-Mileage Array Chicago LA NY Philly Chicago 0 2054 802 738 LA 2054 0 2786 2706 NY 802 2786 0 100 Philly 738 2706 100 0 Dim rm(,) As Double = {{0,2054,802,738},{2054,0,2786,2706}, {802,2786,0,100},{738,2706,100,0}} declares and initializes an array of road-mileages table Some elements of the array are rm(0,0)=0, rm(0,1)=2054, rm(1,2)=2786 GetUpperBound Method After execution of the statement Dim arrayName(m, n) As varType the value of arrayName.GetUpperBound(0) is m, and the value of arrayName.GetUpperBound(1) is n. 第几维的上界,下界恒为0 Dim seat(20, 15) As Integer seat.GetUpperBound(0) is 20 seat.GetUpperBound(1) is 15 ReDim a Two-Dimensional Array An already-created array can be resized with ReDim arrayName(m, n) no matter it is a sized or unsized array But it will loses the current contents, or with ReDim Preserve arrayName(m, n) • When Preserve is used, only the columns (the right most dimension) can be resized • ReDim cannot change the number of dimensions in the array. 如果定义这个多维数组时,根本就不知道每一维的大小。 可以这样定义二维数组 Dim a(,) As DataType 可以这样定义三维数组 Dim a(,,) As DataType …… Filling a Two-Dimensional Array with a Text File Dim rm(3, 3) As Double 'road mileage Dim rowOfNums() As String =IO.File.ReadAllLines("Distances.txt") Dim line, data() As String For i As Integer = 0 To 3 line = rowOfNums(i) 'The string consists 4 numbers data = line.Split(","c) 'The 4 distances For j As Integer = 0 To 3 rm(i, j) = CDbl(data(j)) Next Next Private Sub btnShow_Click(…) Handles btnShow.Click Dim Row, Col As Integer Row = CInt(txtOrig.Text) Col = CInt(txtDest.Text) If (Row >= 1 And Row <= 4) And (Col >= 1 And Col <= 4) Then txtMiles.Text = CStr(rm(Row - 1, Col - 1)) Else MessageBox.Show(“the numbers must between 1 and 4", "Error") End If End Sub Comments and Exercises Comments6.4 P245 Exercises6.4 P245