Reputation: 85
vv
After completing my school assignment on simple array sorts I came up with this question. Say I have a textbox with a name in it. Right beside that I have a textbox with number in it. Exp txtBox1 = "John Doe"
, txtBox2 = 8
. Lets say I have 10 rows. that would be 20 text boxes. How could I randomly sort these by name keeping all like numbers together in sequential order. Output should look something like this. The key here is to randomly sort the names within the same number group.
This is the code that I have. it is slightly different in the fact that it has 3 column of textbox and 8 rows. This randomly sort the 3 rows keeping the information together in the same row. John Doe, 3, phonenumber. and then puts the information in a mirror image of textboxs. the number represents a skill level so I need alike skill levels to play alike skill levels but randomly sorted within there skill level. Which this does not have. I cant having a 3 play a 7. I hope this makes since. Its almost as if I need a random order inside a sequencial order.
Dim ListOfValues As New List(Of List(Of String))
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.txtA1.Focus()
End Sub
Private Sub AddTB(row As Integer, column As Integer, start As Char)
Dim tb As New TextBox
Dim offset As Integer = Math.Sign(Asc(start) - 65) * (100 + tb.Width * 3)
tb.Name = "txt" & Chr(row + Asc(start)) & column.ToString
tb.Text = tb.Name
tb.Location = New Point(((column - 1) * tb.Width) + offset, (row * tb.Height))
Me.Controls.Add(tb)
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'this adds the data from the textboxes to the list. each row of data is a list
'inside the list. the controls collection can be indexed by control name.
'this makes it easy to access a specific control by using a naming pattern.
Button1.Enabled = True
For I = 0 To 7
ListOfValues.Add({Me.Controls("txt" & Chr(I + 65) & "1").Text, _
Me.Controls("txt" & Chr(I + 65) & "2").Text, _
Me.Controls("txt" & Chr(I + 65) & "3").Text}.ToList)
Next
ListOfValues = ShuffleInfo(ListOfValues)
'This fills the other textboxes with the data from the shuffled list
For I = 0 To 7
Me.Controls("txt" & Chr(I + 83) & "1").Text = ListOfValues(I)(0)
Me.Controls("txt" & Chr(I + 83) & "2").Text = ListOfValues(I)(1)
Me.Controls("txt" & Chr(I + 83) & "3").Text = ListOfValues(I)(2)
Next
End Sub
Private Function ShuffleInfo(ValuesToShuffle As List(Of List(Of String))) As List(Of List(Of String))
'this follows the same basic routine you were using, swapping each item with a random item.
Dim rand As New Random(Now.Millisecond)
For counter = 0 To ValuesToShuffle.Count - 1
Dim n = rand.Next(counter + 1)
Dim temp As List(Of String) = ValuesToShuffle(counter)
ValuesToShuffle(counter) = ValuesToShuffle(n)
ValuesToShuffle(n) = temp
Next
ShuffleInfo = ValuesToShuffle
Button1.Enabled = False
End Function
Upvotes: 0
Views: 191
Reputation: 5545
I think the others missed some important information from your post, if you want to know how to do this by sorting an array, here is what I would do.
Private sList As String() = Array.CreateInstance(GetType(String), 0)
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'Resize the array
ReDim Preserve sList(sList.Length)
'Concatenant the 2 strings and put them into the array
sList(sList.Length - 1) = TextBox1.Text & " " & TextBox2.Text
'Sort the array of strings
Array.Sort(sList)
'Put the array into a StringBuilder so we can display in a 3rd textbox
Dim SB As New System.Text.StringBuilder()
For Each s As String In sList
SB.AppendLine(s)
Next
'Display the text
TextBox3.Text = SB.ToString
End Sub
This code assumes 3 textboxes, the 3rd allows multi-line and is expanded to show multiple lines. It also assumes a standard button to take the values from the 2 textboxes and add to your array.
Upvotes: 0
Reputation: 3615
A slightly different version of Magnus' answer:
Dim list As New List(Of KeyValuePair(Of String, Integer)) From
{
New KeyValuePair(Of String, Integer)("John Doe", 8),
New KeyValuePair(Of String, Integer)("Mary Jane", 3),
New KeyValuePair(Of String, Integer)("Mary Jane", 5),
New KeyValuePair(Of String, Integer)("Peter", 6),
New KeyValuePair(Of String, Integer)("Arne", 5)
}
Dim rand as New Random()
' Note: if you don't want them sorted alphabetically by name,
' then omit "item.Key," from the Order By clause.
list = (From item In list
Select item
Order By item.Value, item.Key, rand.Next).ToList
Upvotes: 0
Reputation: 46967
Something like this:
void Main()
{
var list = new List<Test>()
{
new Test(){ Name = "John Doe", Value = 3 },
new Test(){ Name = "Mary Jane", Value = 3 },
new Test(){ Name = "Peter", Value = 3 },
new Test(){ Name = "Arne", Value = 4 },
new Test(){ Name = "Arne", Value = 4 }
};
var rand = new Random();
var res = list.OrderBy(l => l.Value).ThenBy(l => rand.Next()).ToList();
//Bind GridView/ListView with res as datasource here
}
public class Test
{
public string Name { get; set; }
public int Value { get; set; }
}
EDIT:
And here is the VB version
Private Sub Main()
Dim list = New List(Of Test)
list.Add(New Test("John Doe", 2))
list.Add(New Test("Mary Jane", 3))
list.Add(New Test("Peter", 4))
list.Add(New Test("Arne", 5))
Dim rand = New Random()
list = list.
OrderBy(Function(l) l.Value).
ThenBy(Function(l) rand.Next()).
ToList()
End Sub
Public Class Test
Public Sub New(name As String, value As Int32)
Me.Name = name
Me.Value = value
End Sub
Public Property Name As String
Public Property Value As Int32
End Class
Upvotes: 4