[英]Sort array numerically, with strings and integers
i have an array which has a name and a score next to it, i need it to be sorted high to low. 我有一个数组,数组旁边有一个名称和一个分数,我需要将其从高到低排序。 i already have it sorted alphabetically. 我已经按字母顺序对其进行了排序。
Dim reply3 As String
Dim name As String
Dim score As Integer = 0
Dim classnum As Integer
Dim filePath As String
Dim reply As Integer
Dim reply2 As Integer
Dim strline As String
Dim array() As String
Sub Main()
Console.Title = "Math Test"
Console.WriteLine("Do you want to start the test or view previous results? Press 1 for test, 2 for results")
reply = Console.ReadLine
If reply > 2 Then
MsgBox("Invalid Reply Press Ok to end")
End
End If
If reply = 2 Then
Console.WriteLine("What class do you want to see the results of? 1, 2, or 3?")
reply2 = Console.ReadLine()
End If
If reply2 > 3 Then
MsgBox("Invalid Reply Press Ok to exit")
End
End If
Select Case reply2
Case 1
Dim results1 As String = File.ReadAllText("Z:\scores class 1.txt")
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
System.Array.Sort(array)
For i As Integer = 0 To array.Length - 1
Console.WriteLine(array(i))
Next
ElseIf Console.ReadLine = 2 Then
End
End If
Console.ReadLine()
Case 2
Dim results1 As String = File.ReadAllText("Z:\scores class 2.txt")
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
System.Array.Sort(array)
For i As Integer = 0 To array.Length - 1
Console.WriteLine(array(i))
Next
ElseIf Console.ReadLine = 2 Then
End
End If
Console.ReadLine()
Case 3
Dim results1 As String = File.ReadAllText("Z:\scores class 3.txt")
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
System.Array.Sort(array)
For i As Integer = 0 To array.Length - 1
Console.WriteLine(array(i))
Next
ElseIf Console.ReadLine = 2 Then
End
End If
Console.ReadLine()
End Select
If reply = 1 Then
Console.WriteLine("What is your name?")
name = Console.ReadLine
Console.WriteLine("What class are you in, 1, 2 or 3?")
classnum = Console.ReadLine
If classnum < 1 Then
MsgBox("Invalid Class number")
End
ElseIf classnum > 3 Then
MsgBox("Invalid Class number")
End
End If
Console.WriteLine("What is 9+10 ?")
If Console.ReadLine = 19 Then
score += 1
End If
Console.WriteLine("What is 5x10 ?")
If Console.ReadLine = 50 Then
score += 1
End If
Console.WriteLine("What is 122÷2 ?")
If Console.ReadLine = 61 Then
score += 1
End If
Console.WriteLine("What is 424 + 10 ?")
If Console.ReadLine = 434 Then
score += 1
End If
Console.WriteLine("What is 234 x 3 ?")
If Console.ReadLine = 702 Then
score += 1
End If
Console.WriteLine("What is 10 x 10 ?")
If Console.ReadLine = 100 Then
score += 1
End If
Console.WriteLine("What is 12 x 64 ?")
If Console.ReadLine = 768 Then
score += 1
End If
Console.WriteLine("What is the value of N in this equation? 2n+6=10?")
If Console.ReadLine = 4 Then
score += 1
End If
Console.WriteLine("What is 9 x 73 ?")
If Console.ReadLine = 657 Then
score += 1
End If
Console.WriteLine("What is 1 + 1 ?")
If Console.ReadLine = 2 Then
score += 1
End If
MsgBox("Your score was " & score & " Click ok to finish.")
Dim output1 As String = name & " " & score & "-"
Select Case classnum
Case 1
filePath = System.IO.Path.Combine(
My.Computer.FileSystem.SpecialDirectories.MyDocuments, "scores class 1.txt")
My.Computer.FileSystem.WriteAllText(filePath, output1, True)
Case 2
filePath = System.IO.Path.Combine(
My.Computer.FileSystem.SpecialDirectories.MyDocuments, "scores class 2.txt")
My.Computer.FileSystem.WriteAllText(filePath, output1, True)
Case 3
filePath = System.IO.Path.Combine(
My.Computer.FileSystem.SpecialDirectories.MyDocuments, "scores class 3.txt")
My.Computer.FileSystem.WriteAllText(filePath, output1, True)
End Select
End If
End Sub
I need the array called array to be sorted numerically. 我需要称为数组的数组进行数字排序。 i will add the option for the user to choose if he/she wants further sorting after it has been done alphabetically. 我将为用户添加选项,以便用户按字母顺序选择是否要进一步排序。
Strings are not numbers. 字符串不是数字。 They are text. 它们是文本。
In string format, they are simply characters ( numerals ) and they do not and will not sort numerically: 在字符串格式中,它们只是字符( 数字 ),它们不是也不 将按数字排序:
Dim myVals As String() = {"5", "07", "178", "9", "899", "42", "3"}
' add two of the "numbers"
Console.WriteLine("{0} + {1} = {2}", myVals(0),
myVals(1), (myVals(0) + myVals(1)))
Array.Sort(myVals)
Array.Reverse(myVals)
For Each s As String In myVals
Console.Write("{0} ", s)
Next
Output: 输出:
5 + 07 = 507 5 + 07 = 507
9 899 5 42 3 178 07 9 899 5 42 3 178 07
The values do not add as expected, because they are not numbers. 值未按预期添加,因为它们不是数字。 Instead, the code simply concatenates (glues together) two bits of string. 取而代之的是,代码仅将字符串的两位连接在一起(粘合在一起)。 The array contents sort as characters also. 数组内容也按字符排序。 When sorting, "9"
will always be seen as larger than the others. 排序时, "9"
将始终被视为大于其他值。
This applies to dates stored as strings as well. 这也适用于以字符串形式存储的日期。 "9/16/1914" will always evaluate larger/later than "12/1/2015". “ 9/16/1914”将始终大于/晚于“ 12/1/2015”。
Because as text, the lexicographical or alphabetical order used (0,1,2,3,4,5,6,7,8,9). 因为作为文本,所以按字典顺序或字母顺序使用(0,1,2,3,4,5,6,7,8,9)。
Stored as string, numbers loose their numeric value (until converted). 数字以字符串形式存储,失去其数值(直到转换)。 "9"
sorts higher than "899"
because "9"
is higher than "899"
. "9"
高于种"899"
,因为"9"
高于 "899"
。 The same way that "Able" and "Baker" will sort based on "A" and "B". “ Able”和“ Baker”将基于“ A”和“ B”进行排序的方式相同。 The "07"
sorts lowest because of the zed. 由于zed, "07"
排序最低。 The numerical value is ignored because they are strings (text). 数值被忽略,因为它们是字符串(文本)。
The same is true for string "dates" - they are not dates and have no date value. 字符串“ dates”也是如此-它们不是日期,也没有日期值。 Your brain interprets them as dates based on the pattern; 您的大脑会根据模式将它们解释为日期。 to the computer, they remain text and "9/16/yyyy"
will evaluate larger than "12/1/yyyy"
. 在计算机上,它们仍然是文本,并且"9/16/yyyy"
计算结果将大于"12/1/yyyy"
。
We now know that there are no integers in string arrays, just numerals. 现在我们知道字符串数组中没有整数,只有数字。 But also, if you have 2 pieces of data, you need to store them separately if you want to use them individually. 但是,如果您有2个数据,则要单独使用它们,则需要分别存储它们。 A Class is ideal for this: 类是理想的选择:
Public Class Student
Public Property Name As String
Public Property Score As Integer
Public Sub New()
End Sub
' overload
Public Sub New(n As String, s As Integer)
Name = n
Score = s
End Sub
Public Overrides Function ToString() As String
Return String.Format("{0} ({1})", Name, Score)
End Function
End Class
Notice that the name and score are stored as the correct data type which will allow code to use the Score as a numeric value. 请注意,名称和分数存储为正确的数据类型,这将使代码将分数用作数字值。 Unlike using 2 arrays, the name cannot become detached from the score. 与使用2个数组不同,该名称不能与乐谱分离。
Note also that ToString()
allows us to display the data however we want. 还请注意, ToString()
允许我们根据需要显示数据。 Just because we want to show the name and score together does not mean we must glue that information together. 仅仅因为我们想显示名称和分数并不意味着我们必须将这些信息粘合在一起。 Sample output: 样本输出:
Charlie (89) 查理(89)
Give up your arrays (and ArrayLists)! 放弃您的数组(和ArrayList)! It is the 21st Century and we have Typed collections (called Generics ): 这是21世纪,我们有Typed集合(称为Generics ):
Private Students As List(of Student) ' declaration
Students
is a collection which can only store Student
objects, which in turn contains 2 pieces of data. Students
是一个只能存储Student
对象的集合,而Student
对象又包含2个数据。 Let's add some: 让我们添加一些:
Students = New List(Of Student) ' create List instance
Dim stud As New Student ' create new student
stud.Name = "Harvey" ' set props
stud.Score = 72 ' 72 is a NUMBER
Students.Add(stud) ' add to collection
' fast way, using the overload, no temp student object needed
Students.Add(New Student("Bob", 67))
Students.Add(New Student("Hoover", 82))
Students.Add(New Student("Ziggy", 97))
...
Students.Add(New Student("Zoey", 89))
Note that we do not have to set the size of the List(of Student)
- it grows as it needs to. 请注意,我们不必设置List(of Student)
的大小-它会根据需要增加。 You can still reference them by element/position: Students(0)
is a Student
object, and Students(0).Name
will be the name of the student in the first slot ("Harvey"). 您仍然可以按元素/位置引用它们: Students(0)
是Student
对象, Students(0).Name
将是第一个位置(“ Harvey”)中学生的名称。
Students = Students.OrderByDescending(Function(x) x.Score).ToList()
This creates a new collection in the desired order. 这将以所需顺序创建一个新集合。 To sort matching scores by name: 按名称对匹配分数进行排序:
Students = Students.OrderByDescending(Function(x) x.Score).
ThenBy(Function(q) q.Name).ToList()
' print the contents:
For Each st As Student In Students
Console.WriteLine(st)
Next
The result after adding several matching scores of 89
: 加上多个匹配分数89
后的结果:
Ziggy (97) 齐吉(97)
Charlie (89) 查理(89)
Echo (89) 回声(89)
Tango (89) 探戈(89)
Zoey (89) 佐伊(89)
Hoover (82) 胡佛(82)
Harvey (72) 哈维(72)
Bob (67) 鲍勃(67)
To track multiple class scores (hinted at in the code), you could add an Id
(1,2,3) or Code
("101", "201", "303") to the class to qualify which class, series or set each User-Score belongs. 要跟踪多个班级成绩(在代码中的提示),您可以向班级添加一个Id
(1,2,3)或Code
(“ 101”,“ 201”,“ 303”)以限定哪个班级,系列或设置每个用户分数所属的。 Use an additional .Where()
above to get just a subset of the master list. 使用上面的其他.Where()
仅获得主列表的一个子集。
Finally, rather than storing score sets to individual files, the entire list in its current state can be serialized and saved in 3 or 4 lines of code. 最后,与其将分数集存储到单个文件中,不如将其当前状态的整个列表序列化并保存为3或4行代码。
Strings do not contain numbers, nor Dates . 字符串不包含数字,也不包含Dates 。 They are text. 它们是文本。
Don't store individual data elements as one, if you want to use them individually. 如果要单独使用单个数据元素,请不要将其存储为一个。
What you have is a essentially a multidimensional array containing multiple data types (but in your case, you have concatenated each row into a single string). 实际上,您所拥有的是一个包含多种数据类型的多维数组(但在您的情况下,您已将每一行连接到一个字符串中)。 There isn't a catch-all way to handle this situation, but here are a few methods to consider: 没有一种万能的方法来处理这种情况,但是这里有一些需要考虑的方法:
One multidimensional object array: 一个多维对象数组:
Dim array(,) As Object = {{"Student1", 95},{"Student2", 87}...}
Two parallel, one dimensional arrays: 两个平行的一维数组:
Dim names() As String = {"Student1","Student2"...}
Dim scores() As Integer = {95, 87...}
Create a Class or Struct: 创建一个类或结构:
Public Class Student
Property name As String
Property score As Integer
End Class
These are all generally better ways of storing your data, but typically put the burden of sorting your data on you. 这些通常都是更好的存储数据的方法,但通常会给您增加对数据进行排序的负担。 Which leads me to the final option... 这导致我最终选择...
Hack together a workaround: 共同解决一个变通方法:
This is essentially what you've already done- concatenated a string with an integer to allow use of the built-in Sort
procedure. 本质上,这就是您已经完成的操作-将字符串与整数连接起来,以允许使用内置的Sort
过程。 You can use the same trick to sort by score, but you have to 0-pad your integers if you want them to sort correctly. 您可以使用相同的技巧按分数排序,但是如果希望整数正确排序,则必须将其0填充。 See code below, but you've been warned: these type of solutions are invariably easier to implement in the short term but grow unwieldy and less useful in the long term, often needing to be replace by one of the "better" solutions above. 请参阅下面的代码,但是您已经得到警告:这类解决方案在短期内始终易于实现,但从长远来看却变得笨拙且用处不大,通常需要替换为上面的“更好”的解决方案之一。
Private Sub FlipStrings(ByRef students() As String)
If students Is Nothing Then Exit Sub
For i As Integer = 0 To UBound(students)
Dim parts() As String = Split(students(i))
If parts Is Nothing OrElse UBound(parts) <> 1 Then Continue For
If IsNumeric(parts(0)) Then
students(i) = parts(1) & " " & CInt(parts(0))
ElseIf IsNumeric(parts(1)) Then
Do Until len(parts(1)) = 3 'Assuming max score of 100'
parts(1) = "0" & parts(1)
Loop
students(i) = parts(1) & " " & parts(0)
End If
Next
End Sub
I wrote this so you can still store and display your array exactly as before. 我写了这个,所以您仍然可以像以前一样存储和显示数组。 Now, to sort by score 现在,按分数排序
FlipStrings(array)
System.Array.Sort(array)
FlipStrings(array)
should give you exactly what you're looking for. 应该给您您想要的东西。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.