Проверьте, ВСЕ ли элементы в массиве существуют в словаре - PullRequest
0 голосов
/ 07 июня 2018

У меня есть какой-то устаревший код, который состоит из:

A Dictionary (dictParts), заполненных во время запуска ок.350 000 предметов (не изменяется во время выполнения).dictParts является System.Collections.Generic.Dictionary(Of String, System.Data.DataRow).

Каждый элемент в dictParts является System.Collections.Generic.KeyValuePair(Of String, System.Data.DataRow).

An Array (arrOut), в который часто добавляются и удаляются элементы (обычно от 2 до 6 элементов в массиве).arrOut - это System.Array, содержащий только string с.

Каждый раз, когда массив изменяется, мне нужно посмотреть, есть ли:

  • Все элементы в массиве существуют вindex
  • Некоторые элементы в массиве существуют в индексе

Я предполагаю, что цикл по индексу 350 000 при каждом изменении массива приведет к значительному снижению производительности и будет выглядеть какLINQ, чтобы помочь.

Я пробовал следующее:

Private Sub btnTest_Click(sender As System.Object, e As System.EventArgs) Handles btnTest.Click

    Dim dictParts = New Dictionary(Of Integer, String) _
                    From {{1, "AA-10-100"}, _
                          {2, "BB-20-100"}, _
                          {3, "CC-30-100"}, _
                          {4, "DD-40-100"}, _
                          {5, "EE-50-100"}}


    Dim arrOut() As String = {"AA-10-100", "BB-20-100", "CC-30-100"}

    'Tried
    Dim allPartsExist As IEnumerable(Of String) = arrOut.ToString.All(dictParts)
    'And this
    Dim allOfArrayInIndex As Object = arrOut.ToString.Intersect(dictParts).Count() = arrOut.ToString.Count

End Sub

Я продолжаю получать ошибки: Невозможно привести объект типа 'System.Collections.Generic.Dictionary 2[System.Int32,System.String]' to type 'System.Collections.Generic.IEnumerable 1 [System.Char] '.

Пожалуйста, кто-нибудь может посоветовать, где я иду не так.

Ответы [ 2 ]

0 голосов
/ 07 июня 2018

Выполнение теста с HashSet по сравнению с исходным Dictionary, содержащим 350 000 значений, с соответствующими элементами, добавленными последними к Dictionary, HashSet более чем в 15 000 раз быстрее.

Тестированиепо сравнению с исходным Dictionary:

Dim AllInDict = arrOut.All(Function(a) dictParts.ContainsValue(a))
Dim SomeInDict = arrOut.Any(Function(a) dictParts.ContainsValue(a))

Создание HashSet требует времени четырех Dictionary поисков, так что не стоит, если вы изменяете Dictionary чаще, чем каждыйчетыре поиска.

Dim hs = New HashSet(Of String)(dictParts.Values)

Затем вы можете использовать HashSet для проверки членства, что по крайней мере в 14 000 раз быстрее, чем поиск по всему Dictionary (конечно, в среднем это будет около 50%быстрее).

Dim AllInDict2 = arrOut.All(Function(a) hs.Contains(a))
Dim SomeInDict2 = arrOut.Any(Function(a) hs.Contains(a))
0 голосов
/ 07 июня 2018

Чтобы узнать что-то, я попробовал хэш-сет, предложенный @ emsimpson92.Может быть, это может работать для вас.

Imports System.Text
Public Class HashSets
    Private shortList As New HashSet(Of String)
    Private longList As New HashSet(Of String)

    Private Sub HashSets_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        shortList.Add("AA-10-100")
        shortList.Add("BB-20-100")
        shortList.Add("DD-40-101")
        Dim dictParts As New Dictionary(Of Integer, String) _
        From {{1, "AA-10-100"},
                          {2, "BB-20-100"},
                          {3, "CC-30-100"},
                          {4, "DD-40-100"},
                          {5, "EE-50-100"}}
        For Each kv As KeyValuePair(Of Integer, String) In dictParts
            longList.Add(kv.Value)
        Next
    'Two alternative ways to fill the hashset
    '1. remove the New from the declaration
    'longList = New HashSet(Of String)(dictParts.Values)
    '2. Added in Framework 4.7.2
    'Enumerable.ToHashSet(Of TSource) Method (IEnumerable(Of TSource))
    'longList = dictParts.Values.ToHashSet()
    End Sub

    Private Sub CompareHashSets()
        Debug.Print($"The short list has {shortList.Count} elements")
        DisplaySet(shortList)
        Debug.Print($"The long list has {longList.Count}")
        shortList.ExceptWith(longList)
        Debug.Print($"The items missing from the longList {shortList.Count}")
        DisplaySet(shortList)
        'Immediate Window Results
        'The Short list has 3 elements
        '{ AA-10-100
        'BB-20 - 100
        'DD-40 - 101
        '}
        'The Long list has 5
        'The items missing from the longList 1
        '{ DD-40-101
        '}
    End Sub

    Private Shared Sub DisplaySet(ByVal coll As HashSet(Of String))
        Dim sb As New StringBuilder()
        sb.Append("{")
        For Each s As String In coll
            sb.AppendLine($" {s}")
        Next
        sb.Append("}")
        Debug.Print(sb.ToString)
    End Sub

    Private Sub btnCompare_Click(sender As Object, e As EventArgs) Handles btnCompare.Click
        CompareHashSets()
    End Sub
End Class

Примечание. Код, заполняющий хэш-набор из словаря, не будет работать, если в словаре есть повторяющиеся значения (не дублирующиеся ключи, дублирующиеся значения), поскольку элементы вхешсет должен быть уникальным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...