сравнить два массива и скопировать уникальный элемент из второго в первый массив VB.NET - PullRequest
0 голосов
/ 25 февраля 2020

У меня есть два массива: TempSubject(), который содержит список предметов, и friRoutine(), который указывает, когда предметы преподаются.

Мне нужно применить правило, согласно которому ни один конкретный предмет не может преподаваться дважды в определенный c день. У меня есть функция с именем DetectDuplicate(friRoutine, Tempsubject(i)), которая проверяет friRoutine() с помощью TempSubject() и находит, содержит ли friRoutine конкретную тему. Если нет, то добавьте этот уникальный предмет к friRoutine. В противном случае продолжайте через l oop для следующего предмета. Мой код представлен ниже следующим образом:

Dim TempSubject() As String = {"Maths","English","Sanskrit","Sanskrit","Urdu","Urdu","Urdu","French","French","French","Physical Education","Physical Education","Game","Game", "Science"}

dim c4 as integer = 0
dim limitcounter = 0
dim friRoutine() as string
reedim friRoutine(6)

While c4 < TempSubject.Length
    If DetectDuplicate(friRoutine, TempSubject(c4)) = False And limitcounter4 < 7 Then
        friRoutine(limitcounter4) = TempSubject(c4)
        'MessageBox.Show(c1 & ": " & limitcounter1 & ": " & tueRoutine(limitcounter1))
        Debug.WriteLine("Friday: " & c4 & ": " & limitcounter4 & ": " & friRoutine(limitcounter4))
        TempSubject.RemoveAt(c4)
        limitcounter4 = limitcounter4 + 1
    End If
    c4 = c4 + 1
End While


Private Function DetectDuplicate(ByVal arr As Array, ByVal str As String) As Boolean
    Dim numcount As Integer = 0
    For numcount = 0 To arr.Length - 1
        If arr(numcount) = str Then
            Return True
        End If
    Next
    Return False
End Function

Выход должен быть

friRoutine = Math, english, sanskrit, Urdu, French, Physical education, game

, но, к сожалению, Engli sh отсутствует. вывод:

friRoutine = Math, sanskrit, Urdu, French, Physical education, game, science

Я боюсь использовать мой код, поскольку он может испортить весь процесс в любой момент времени. Я думаю, что проблема с функцией DetectDuplicate ()

Редактировать (из комментария)

Я должен удалить использованные элементы. Моя оригинальная программа будет состоять из 42 предметов и 6 дней. 7 периодов каждый день. Например, если я выбрал 7 уникальных предметов для понедельника, то в течение следующих 6 дней у меня должно быть только 35 предметов, которые нужно отрегулировать на оставшиеся 5 дней.

Ответы [ 2 ]

4 голосов
/ 25 февраля 2020

Первое, что я хотел бы сделать, это преобразовать массивы в обобщенные c списки. Итак, это:

Dim TempSubject() As String = {"Maths","English","Sanskrit","Sanskrit","Urdu","Urdu","Urdu","French","French","French","Physical Education","Physical Education","Game","Game", "Science"}
Dim friRoutine() As String

Получается так:

Dim TempSubject As New List(Of String) From {"Maths","English","Sanskrit","Sanskrit","Urdu","Urdu","Urdu","French","French","French","Physical Education","Physical Education","Game","Game", "Science"}
Dim friRoutine As New List(Of String)(6)

Вы можете получить доступ к элементам в этих списках по индексу, как с массивами, но теперь он становится MUCH проще делать такие вещи, как добавлять или удалять записи. По крайней мере , я бы сделал это для коллекции friRoutine; есть некоторый аргумент для массива таким образом, что TempSubject используется в этом коде, но даже там данные, скорее всего, пришли куда-то, что вместо этого могло бы оправдать List (Of String).

Это сделано, вы Можно значительно упростить код:

friRoutine.AddRange(TempSubject)
friRoutine = friRoutine.Distinct().Take(7).ToList()

Или, чтобы показать весь образец:

Dim TempSubject = {"Maths","English","Sanskrit","Sanskrit","Urdu","Urdu","Urdu","French","French","French","Physical Education","Physical Education","Game","Game", "Science"}

Dim friRoutine As New List(Of String)(TempSubject.Distinct().Take(7))
For i As Integer = 0 to friRoutine.Count - 1
    Debug.WriteLine($"Friday: {i} : {friRoutine(i)}")
Next 

И теперь, когда мы видим данные для friRoutine можно вычисляется из одной строки кода, возникает вопрос: а нужна ли нам вообще отдельная коллекция?

Что касается исходного кода, большая проблема заключалась в следующей строке:

TempSubject.RemoveAt(c4)

Это изменило коллекцию, все еще проходя по ней. Все будет двигаться вперед, что приведет к пропуску некоторых элементов.

0 голосов
/ 25 февраля 2020

Просто используйте Enumerable.Distinct<T>()

Dim TempSubject = {"Maths","English","Sanskrit","Sanskrit","Urdu","Urdu","Urdu","French","French","French","Physical Education","Physical Education","Game","Game", "Science"}

Dim friRoutine = TempSubject.Distinct().ToArray()

Если вы хотите вместо этого вывод списка, это просто

Dim friRoutine = TempSubject.Distinct().ToList()

, так как и массив, и список являются перечисляемыми , TempSubject может быть либо массивом, либо списком.

...