VB.net | Поиск дубликатов в многомерном массиве

#vb.net #multidimensional-array

#vb.net #многомерный массив

Вопрос:

У меня есть две формы: Act9.vb и List.vb. Код в обеих формах приведен ниже. Я использую vb.net «4.7.2» в Visual Studio. Я уже некоторое время очень разочарован этой программой. По какой-то причине программа проверяет только новых клиентов на соответствие первому и второму клиентам, которые уже есть в списке. Например, если в списке есть следующие записи:

 ╔═════════╦═════════════╗
║ ClientA ║ 32423223343 ║
╠═════════╬═════════════╣
║ ClientB ║ 23422322343 ║
╠═════════╬═════════════╣
║ ClientC ║ 23423423423 ║
╠═════════╬═════════════╣
║ ClientD ║ 43533453333 ║
╠═════════╩═════════════╣
║ etc...                ║
╚═══════════════════════╝
  

Затем, если я попытаюсь изменить ClientA или ClientB (нажав btnModify и затем введя «ClientA» /»ClientB» в поле ввода), тогда это сработает, но если я попробую то же самое с ClientC, D, E и т.д. это не так. Я получаю это сообщение: «Этот клиент не существует. Пожалуйста, попробуйте еще раз. »
То же самое с добавлением новых клиентов: это не позволит мне добавить ClientA или B дважды, но если я попытаюсь добавить клиент C еще раз, он не поймет, что он уже находится в многомерном массиве, и позволит мне добавить его во второй раз.

Если кто-то знает что-нибудь, что может помочь, пожалуйста, поделитесь. Заранее спасибо!

 Public Class Act9
    Public Clients(1, 1) As String
    Public size As Integer = 0

    Sub Add()
        Dim tempClient As String
        Dim tempTel As String

        tempClient = InputBox("Please enter the clients name :", "Name")

        If Duplicate(tempClient) Then
            MsgBox("This client already exists")

        Else
            tempTel = InputBox("Please enter the client's phone number:", "Phone number")

            Clients(0, size) = tempClient
            Clients(1, size) = tempTel

            size  = 1
            ReDim Preserve Clients(1, size)
        End If
    End Sub

    Function Duplicate(ByVal tempClient As String) As Boolean
        Dim output As Boolean = False
        For i As Integer = LBound(Clients) To UBound(Clients)
            If Clients(0, i) = tempClient Then
                output = True
            End If
        Next
        Return output
    End Function

    Private Sub BtnAdd_Click(sender As Object, e As EventArgs) Handles btnAdd.Click
        Add()
    End Sub

    Private Sub btnShow_Click(sender As Object, e As EventArgs) Handles btnShow.Click
        List.ShowDialog()
    End Sub

    Private Sub btnErase_Click(sender As Object, e As EventArgs) Handles btnErase.Click
        ReDim Clients(1, size)
        List.lstClients.Items.Clear()
        size = 0
    End Sub

    Private Sub btnModify_Click(sender As Object, e As EventArgs) Handles btnModify.Click
        modify()
    End Sub

    Sub modify(Optional who As String = Nothing)
        Dim change As Boolean = False

        If who = Nothing Then who = InputBox("Please enter the name of the client you wish to modify:", "Modify")

        For i As Integer = LBound(Clients) To UBound(Clients)
            If Clients(0, i) = who Then
                Clients(0, i) = InputBox("Please enter the new name for the client:", "Name")
                Clients(1, i) = InputBox("Please enter the new phone number for the client", "Phone number")
                change = True
                Exit For
            End If
        Next
        If change = False Then MsgBox("This client doesn't exist. Please try again.")
    End Sub
End Class
  
 Public Class List
    Private Sub List_Load(sender As Object, e As EventArgs) Handles Me.Load
        lstClients.Items.Clear()

        For i As Integer = 0 To Act9.size - 1
            lstClients.Items.Add(Act9.Clients(0, i) amp; vbTab amp; Act9.Clients(1, i))
        Next
    End Sub
End Class
  

Комментарии:

1. Это домашнее задание?

2. Честно говоря, многомерный массив является неоптимальной структурой для использования для такого рода данных. Рассмотрим Dictionary(Of String, String)

3. @Craig Спасибо, спасибо. Это, вероятно, звучит глупо, но я не знал, как это сделать. Я посмотрел и попробовал. Это помогло мне найти и устранить проблему за считанные минуты. Это действительно полезный инструмент! Я не знаю, как выразить свою благодарность за то, сколько времени это сэкономит мне. Еще раз спасибо. =)

4. Я спросил, было ли это домашним заданием, главным образом потому, что оно изменяет данный совет; у вас, вероятно, есть такие параметры, как «необходимо использовать многомерный массив», что означает, что независимо от того, насколько мы умоляем вас изменить его (потому что это в основном дерьмовый способ хранения чего-либо, и я никогда в своей профессиональной жизни их не использовал, даже ни разу, после ухода из академии) вы не можете.

5. Я бы рекомендовал вызвать ваш метод isDuplicate, потому что он возвращает логическое значение. Вызов этого дубликата подразумевает, что переданный объект будет дублироваться

Ответ №1:

@Craig сказал мне использовать точки останова, которые являются идеальными инструментами для этого. Я очень благодарен за совет.

Вот как я в итоге заставил его работать должным образом:

Я заменил LBound и Ubound своей переменной «size» (которая уже занималась подсчетом размера моего многомерного массива).

Цикл For в «Дубликате» становится:

 For i As Integer = 0 To size
            If Clients(0, i) = tempClient Then
                output = True
            End If
        Next
  

Тот, который находится в «Изменить становится:

 For i As Integer = 0 To size
            If Clients(0, i) = who Then
                Clients(0, i) = InputBox("Please enter the new name for the client:", "Name")
                Clients(1, i) = InputBox("Please enter the new phone number for the client", "Phone number")
                change = True
                Exit For
            End If
        Next
  

Ответ №2:

Причина, по которой ваш исходный код не сработал, заключается в том, что вы LBound / UBound в первом измерении, но ваш массив распространяется на второе измерение. Первое измерение имеет значение только от 0 до 1, поэтому вы проверяли только индексы второго измерения 0 и 1 (первые два элемента) для имени:

  For i As Integer = LBound(Clients) To UBound(Clients)
  

Если вы используете

  LBound(Clients, 2) to UBound(Clients, 2)
  

Он получит верхний предел второго измерения, а не первого. UBound использует индексацию на основе 1, тогда как VB использует 0. Если вы хотите то же самое на основе 0, вы можете использовать

 Array.GetUpperBound(Clients, 1)
  

чтобы найти предел второго измерения

Другие советы:

  • ваш метод modify допускает ту же ограничивающую ошибку
  • если бы это было программирование 201, вы, вероятно, использовали бы Список (Client), Client — это класс, имеющий пару строковых свойств для name и tel, и переопределенный метод equals, который сравнивает имя входящего клиента, так что список.Содержит может использоваться для предотвращения дубликатов. В конечном итоге вы, вероятно, также переопределите GetHashCode и используете HashSet (клиента). И все это на самом деле было бы намного проще. Многомерные массивы обычно являются плохим решением для хранения.. ну .. все
  • ваша size переменная является общедоступной; она должна иметь заглавную букву s
  • ваш метод modify — это метод; он должен иметь заглавную букву M. Все методы в .net имеют заглавные начальные буквы
  • возможно, btnErase следует установить размер перед его переопределением
  • ваш метод дублирования проверяет каждый элемент в массиве. Он продолжает проверку, даже если он уже нашел дубликат элемента. Вы можете пропустить ту часть, где вы создаете логическое значение и просто возвращаете True внутри If; ваши ключи всегда находятся в последнем месте, куда вы смотрите, потому что вы перестаете искать, когда их находите 🙂
  • возможно, если вы реализуете метод findIndex, который принимает имя и возвращает индекс того, где находится этот человек, или -1, если он их не нашел, вы можете использовать его как для isDuplicate (вызовите findindex и верните true, если результат больше -1), так и для Modify (найдите индексчеловек и измените их или поместите сообщение Не найдено, если -1 приходит bac). Это означает, что у вас может быть только один метод, который выполняет поиск в массиве, и вы используете его дважды. Это означает, что вы не повторяетесь — принцип разработки программного обеспечения, которого мы стараемся придерживаться. На данный момент ваши методы duplicate и modify имеют один и тот же цикл (с одной и той же ошибкой)

Комментарии:

1. Спасибо за помощь. Это все отличные советы. У меня не было выбора использовать что-то другое, кроме многомерного массива, поскольку это было частью задания. Я понимаю, что это не очень хороший метод хранения. Еще раз спасибо за вашу помощь.