2017-03-17 1 views
0

J'ai quelques données de colonne que j'ai lues dans un fichier et mises dans une liste puis trier par ordre alphabétique.Recherche binaire dans une liste et renvoi à une colonne spécifique de la liste

// Le fichier

Hoummos, 0,75

Chili, 0,50

Tabouli, 1,25

Tzatziki, 0,50

// Déclaration des variables et des propriétés publiques

Dim extraList As List(Of extra) 

Public Class extra 
    Implements IComparable(Of extra) 
    Public Property Name As String 
    Public Property Price As Decimal 
    'Public Property extraList As List(Of extra) 

    Public Function CompareTo(other As extra) As Integer Implements IComparable(Of extra).CompareTo 
     Return Me.Name.CompareTo(other.Name) 
    End Function 
End Class 

// met les données dans une liste et trie

Sub Get_Extras_List() 
    'Reads the extras file and puts the information into a list, splitting the name of the extra and the price into separate columns 
    Dim allExtras = From line In System.IO.File.ReadLines("C:\Users\ExtrasList.txt") 
        Let Columns = line.Split(","c) 
        Where Columns.Length = 2 
        Let Price = Decimal.Parse(Columns(1).Trim()) 
        Let Name = Columns(0).Trim() 
        Select New extra With {.Name = Name, .Price = Price} 

    extraList = allExtras.ToList() 

    'Sort the list alphabetically 
    extraList.Sort() 
End Sub 

Maintenant, je dois coder une méthode qui permet à l'utilisateur de saisir une somme supplémentaire et chercher à l'aide d'une recherche binaire pour voir si elle existe. Jusqu'à présent, j'ai essayé cela, mais ça ne marche pas et même si c'était le cas, comment puis-je obtenir une valeur vraie ou fausse? (Si elle existe ou non?)

Sub Search_Extras_List() 
    Dim strSearchExtra As String = Console.ReadLine() 
    Console.WriteLine(vbLf & "BinarySearch for '{0}':", strSearchExtra) 
    Dim index As Integer = 
     List(Of extra).BinarySearch(extraList.Name, strSearchExtra) 
End Sub 

Enfin, je dois obtenir l'utilisateur de choisir l'un des extras puis ajouter le prix de celui-ci au prix total. Comment puis-je me référer au prix? extraList.Price? extra.Prix?

Répondre

0

Si vous voulez faire une recherche binaire comme ça, vous devrez écrire un comparateur.

Se référant à List(Of T).BinarySearch Method (T, IComparer(Of T)), il pourrait être

Public Class ExtraComparer 
    Implements IComparer(Of extra) 

    Public Function Compare(ByVal x As extra, ByVal y As extra) As Integer Implements IComparer(Of extra).Compare 

     If x Is Nothing Then 
      If y Is Nothing Then 
       ' If x is Nothing and y is Nothing, they're equal. 
       Return 0 
      Else 
       ' If x is Nothing and y is not Nothing, y is greater. 
       Return -1 
      End If 
     Else 
      ' If x is not Nothing... 
      If y Is Nothing Then 
       ' ...and y is Nothing, x is greater. 
       Return 1 
      Else 
       ' ...and y is not Nothing, compare the names of the two extras. 
       ' 
       Return x.Name.CompareTo(y.Name) 

      End If 
     End If 
    End Function 

End Class 

Ce qui vous permet de tester avec

' Get some item from the data so we know it is present... 
Dim a = extraList(2).Name 
Dim lookFor As New extra With {.Name = a} 
Dim idx = extraList.BinarySearch(lookFor, New ExtraComparer) 
Console.WriteLine($"Index of {a} is {idx}.") 

(bien que vous auriez probablement eu envie de faire une comparaison de chaîne insensible à la casse).

Si l'index renvoyé est négatif, l'élément n'a pas été trouvé. (Voir la documentation lien ci-dessus pour plus de détails.)

Cependant, vous pourriez trouver plus facile à utiliser LINQ:

Dim a = extraList(2).Name 
Dim chosenExtra = extraList.FirstOrDefault(Function(x) x.Name.Equals(a, StringComparison.CurrentCultureIgnoreCase)) 

If chosenExtra IsNot Nothing Then 
    Console.WriteLine($"User chose {chosenExtra.Name} at a price of {chosenExtra.Price}") 
Else 
    Console.WriteLine($"User's choice of ""{a}"" was not found.") 
End If 

J'ai utilisé une comparaison insensible à la casse là-dedans. Il suffit de présenter à l'utilisateur une liste déroulante des options disponibles afin qu'il ne soit pas obligé de le saisir.