Array.Binarysearch mit string

  • C#

Es gibt 6 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Array.Binarysearch mit string

    Seit gegrüßt,

    Ich wähle in einer ComboBox ein Item aus, diese Items befinden sich mit dem selben Namen in einem string Array.
    Nun wenn ich wie gesagt ein Item auswähle möchte ich per Array.Binarysearch<string>(sArray, selctedItem) den Index dieses Items im Array herausfinden.

    Code:

    C#-Quellcode

    1. string search = cbArtikel.SelectedItem.ToString();
    2. int iIndex = Array.BinarySearch<string>(sArtikel, search);


    Leider gibt er hier mir immer negative Zahlen als Index aus.. Woran liegt das ?

    Grüße MrSchabernack
    Hi
    du könntest doch theoretisch die ComboBox direkt an eine Liste binden. BinarySearch erwartet, dass das Array vorsortiert ist, da es für diesen Fall einen performanteren Ansatz, als Array.IndexOf bietet. Allerdings sollten, ist das Array sortiert, immer positive Indices herauskommen. Wenn das nicht der Fall ist, ist das Element nicht enthalten (Index ist dann -1).
    Übrigens: Wenn du es datengebunden löst, kannst du den String lediglich zur Darstellung verwenden und dahinter direkt einen Sinn verankern.

    Gruß
    ~blaze~
    Am besten eignet sich dafür wirklich die Datenbindung. Dazu schnappst du dir einfach eine List(Of T) oder ggf. sogar besser eine System.ComponentModel.BindingList(Of T) und packst da Instanzen eines von dir definierten Typs rein. Der kann bspw. so aussehen:

    Visual Basic-Quellcode

    1. Public Class Something
    2. Private _name As String
    3. Private _handler As Action
    4. Public Property Name As String
    5. Get
    6. Return _name
    7. End Get
    8. Private Set(value As String)
    9. _name = value
    10. End Set
    11. End Property
    12. 'Aktion, die ausgelöst werden soll, sobald das Element selektiert wird, bspw.
    13. Public Sub SomeAction()
    14. _handler()
    15. End Sub
    16. Public Sub New(name As String, handler As Action)
    17. 'Nothing ist für name und handler ungültig ==> Exception werfen
    18. If name Is Nothing Then Throw New ArgumentNullException("name")
    19. If handler Is Nothing Then Throw New ArgumentNullException("handler ")
    20. 'Propertywerte aus Konstruktorinfos übernehmen
    21. Me.Name = name
    22. _handler = handler
    23. End Sub
    24. End Class

    SomeAction ist das Verhalten, das mit dem Item assoziiert wird, Name ist der Anzeigename, also der Text, der in der ComboBox angezeigt werden soll.
    Anschließend setzt du im Code die Elemente der (vorher leeren) ComboBox auf die Liste und DisplayMember auf "Name"; das ist eben der Name der Property, die in der ComboBox angezeigt werden soll.

    Visual Basic-Quellcode

    1. Dim list As New BindingList(Of Something)()
    2. 'items in die Liste füllen
    3. list.Add(New Something("bla", Sub()MessageBox.Show("bla")))
    4. list.Add(New Something("xy", Sub()MessageBox.Show("xy")))
    5. list.Add(New Something("xyz", Sub()MessageBox.Show("xyz")))
    6. 'Liste setzen und die Eigenschaft "Name" als Anzeigenamen selektieren
    7. _myComboBox.DataSource = list
    8. 'Wird DisplayMember nicht gesetzt, wird erst versucht, einen System.ComponentModel.TypeConverter für den Typ zu ermitteln und dort das Element zu
    9. 'einem String zu konvertieren, wenn das nicht geht, wird einfach ToString für das Element aufgerufen.
    10. _myComboBox.DisplayMember = "Name"


    In den Ereignissen der ComboBox kannst du dann eben auf das ausgewählte Item zurückgreifen, indem du es über

    Visual Basic-Quellcode

    1. DirectCast(_myComboBox.SelectedItem, Something)

    castest. In SelectedIndexChanged wäre das dann bspw. bei obigem Beispiel

    Visual Basic-Quellcode

    1. DirectCast(_myComboBox.SelectedItem, Something).SomeAction()


    Durch diese Vorgehensweise wird die ganze Suche überflüssig und das Programm bleibt auch bei großen Elementzahlen weiter schön benutzbar. ;)

    Gruß
    ~blaze~

    MrSchabernack schrieb:

    Leider gibt BinarySearch mir immer negative Zahlen als Index aus.. Woran liegt das ?
    Lies mal die Dokumentation - weil so ist BinarySearch eben:
    Es sucht ja in einer sortierten Auflistung, mittels < / = / >.
    Es kann nun eine genaue Übereinstimmung finden, dann gibt es diesen Index als positiven Integer zurück.

    Oder aber es findet den Index des nächst-größeren Items - diesen Index returnt es als negtativen Integer.
    Du weißt also: ist der Index negativ, ist das Element nicht vorhanden. Aber du weißt damit auch die Einsortier-Position, also falls du das gesuchte element zufügen willst, kennst du nun die Position, wo es einzufügen wäre - allerdings musst du dazu eine winzkleine bitweise Umrechnung der negativen Zahl vornehmen:

    VB.NET-Quellcode

    1. If binarySearchResult < 0 Then
    2. dim insertPosition = Not binarySearchResult ' bit-Umkehrung
    3. '...
    4. endif
    Bingo!

    Muss man halt wissen, aber wenn mans weiß, hat man mit BinarySearch eine sehr nützliche und v.a. phänomenal performante Such-Funktion in sortierten Auflistungen.

    Also immer feste Doku lesen: Mittm Cursor auf .BinarySearch gehen, und F1 drücken - dann öffnet der Browser den richtigen MSDN-Artikel (so gott will)

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ErfinderDesRades“ ()