Получить ключ элемента в объекте Collection - PullRequest
5 голосов
/ 10 апреля 2009

Среда такова, что члены, которые я помещаю в коллекцию, являются безымянными, неидентифицируемыми (чтобы избежать плохих абстракций, и, пожалуйста, не волнуйтесь: участники на самом деле являются другими экземплярами коллекции). Чтобы можно было быстро выполнять поиск, я создаю осмысленное хеш-имя для каждого нового члена и предоставляю его в виде строки ключа в методе Add самой «верхней» коллекции.

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

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

Ответы [ 3 ]

6 голосов
/ 10 апреля 2009

Простым подходом будет использование словаря вместо коллекции. Словарь по сути является ассоциативным массивом ключей, пар элементов и поддерживает поиск его ключей в виде массива. Чтобы использовать словарь, вам нужно добавить ссылку на Microsoft Scripting Runtime. Недостаток использования словаря состоит в том, что он не перечисляется так же, как коллекция. Более сложным решением было бы обернуть коллекцию и словарь, чтобы создать перечислимый словарь, как описано ниже.

NB Для правильной работы NewEnum в VBA модуль класса необходимо экспортировать и вручную отредактировать следующим образом, а затем повторно импортировать.

Public Property Get NewEnum() As IUnknown
Attribute NewEnum.VB_UserMemId = -4
   Set NewEnum = someKeys.[_NewEnum]
End Property

Пример

Option Explicit
Private someKeys As Dictionary
Private someCols As Collection
Public Function Add(o As Object, Key As String) As Object
    someKeys.Add Key, o
    someCols.Add o, Key
End Function
Public Property Get Count() As Long
    Count = someCols.Count
End Property
Public Property Get Item(vKey As Variant) As Object
    Set Item = someCols.Item(vKey)
End Property
Public Sub Remove(vKey As Variant)
    someKeys.Remove vKey
    someCols.Remove vKey
End Sub
Public Property Get NewEnum() As IUnknown
   Set NewEnum = someCols.[_NewEnum]
End Property
Public Property Get Keys() As Variant
    Keys = someKeys.Keys
End Property
Private Sub Class_Initialize()
    Set someKeys = New Dictionary
    Set someCols = New Collection
End Sub
2 голосов
/ 12 мая 2009

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

0 голосов
/ 08 августа 2013

попробуй заменить

Public Function NewEnum() As IUnknown
        Set NewEnum = m_ObjectCollection.[_NewEnum]
End Function

с

Public Function NewEnum() As Collection
        Set NewEnum = m_ObjectCollection
End Function

у меня это сработало.

...