BURTON JOHN
BURTON JOHN

Reputation: 85

how to sort names and numbers?

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

Answers (3)

Steve
Steve

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

Douglas Barbin
Douglas Barbin

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

Magnus
Magnus

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

Related Questions