【问题标题】:How to sort a subset according to some ordered superset?如何根据一些有序超集对子集进行排序?
【发布时间】:2023-03-15 00:55:01
【问题描述】:

假设我有一个未排序的字符串数组;我们称这个集合 A。这个数组中的每个字符串也存在于一个更大的字符串数组集合 B 中,其中较大的数组以某种任意方式排序。

我想对 A 进行排序:

对于A中的每个元素E,

  • A 中出现在 B 中 E 之前的所有其他元素也出现在 A 中 E 之前
  • A 中出现在 B 中 E 之后的所有其他元素也出现在 B 中 E 之前

例如,假设集合 B 为:[Cow, Horse, Pig, Chicken, Goat, Dog]
假设无序集合A为:[Horse, Dog, Pig, Cow]

排序后,集合 A 应如下所示:[Cow, Horse, Pig, Dog]

我对如何解决这个问题的最初想法是构建一个新集合,或者在 VBA 中,一个字符串数组:

  • 声明新数组 C
  • 遍历 B 的元素
    • 如果 B 的元素存在于 A 中,则将元素附加到 C

数组 C 现在包含 A 中的所有元素,按照它们在 B 中出现的顺序排列

虽然我相当有信心这种方法有效(尽管如果 B 远大于 A,则效率不是很高),但我想知道是否有人对如何更有效地执行此操作有一些建议,同时考虑到最佳实践,模块化/灵活性等。我希望在 VBA 中实现这一点,但伪代码就足够了。谢谢! (抱歉格式草率;第一次在这里发帖!)

【问题讨论】:

  • 是的。那可行。效率、最佳实践、模块化/灵活性等都取决于实际的实现。很难审查尚未编写的代码。
  • @Comintern,感谢您的意见。一旦我实现了我所描述的功能,我将更新帖子。

标签: arrays vba sorting


【解决方案1】:

所以,我一直在研究记录集this month on my blog,所以我可以告诉您,您的用例适合使用 ADO 记录集。

在下面的代码中,您可以看到我们有一个主集,然后我们可以过滤到一个子集。同样在代码中,我们对显示排序顺序的变量数组进行快照。然后我们在另一个字段上对主集进行排序,这改变了子集的排序,并且可以在第二个快照中看到。

Option Explicit

'* Tools->References
'ADODB      Microsoft ActiveX Data Objects 6.1 Library  C:\Program Files (x86)\Common Files\System\ado\msado15.dll

Sub Test()

    Dim rstADO As ADODB.Recordset
    Dim fld As ADODB.Field

    Set rstADO = New ADODB.Recordset
    With rstADO
        .Fields.Append "Animal", adVarChar, 20
        .Fields.Append "BirthDay", adDate, FieldAttributeEnum.adFldKeyColumn
        .Fields.Append "ArrivalSequence", adInteger

        .CursorType = adOpenKeyset
        .CursorLocation = adUseClient
        .LockType = adLockPessimistic
        .Open

        .AddNew Array("Animal", "BirthDay", "ArrivalSequence"), Array("Cow", Now() - 200, 1)
        .AddNew Array("Animal", "BirthDay", "ArrivalSequence"), Array("Horse", Now() - 100, 2)
        .AddNew Array("Animal", "BirthDay", "ArrivalSequence"), Array("Pig", Now() - 150, 3)
        .AddNew Array("Animal", "BirthDay", "ArrivalSequence"), Array("Chicken", Now() - 120, 4)
        .AddNew Array("Animal", "BirthDay", "ArrivalSequence"), Array("Goat", Now() - 180, 5)
        .AddNew Array("Animal", "BirthDay", "ArrivalSequence"), Array("Dog", Now() - 140, 5)


        .Filter = "Animal='Cow' or Animal='Dog' or Animal='Pig'  or Animal='Horse'"

        Dim vSnap As Variant
        .MoveFirst
        vSnap = .GetRows

        Debug.Assert vSnap(0, 0) = "Cow"
        Debug.Assert vSnap(0, 1) = "Horse"
        Debug.Assert vSnap(0, 2) = "Pig"
        Debug.Assert vSnap(0, 3) = "Dog"


        '*
        '* Now sort according to birthday
        '*
        .Sort = "BirthDay"


        Dim vSnap2 As Variant
        .MoveFirst
        vSnap2 = .GetRows

        Debug.Assert vSnap2(0, 0) = "Cow"
        Debug.Assert vSnap2(0, 1) = "Pig"
        Debug.Assert vSnap2(0, 2) = "Dog"
        Debug.Assert vSnap2(0, 3) = "Horse"


    End With

End Sub

Excel Development Platform: VBA - Fabricate an ADO Recordset for Sorting and Filtering

【讨论】:

  • 非常感谢!我对 SQL、ActiveX 或任何相关技术几乎一无所知或经验,但我认为现在我有一个开始的地方,因为它似乎与我想要实现的目标直接相关。也许这个不是问的最佳时间和地点,但是您有什么特别建议我阅读的内容,以便我可以直观地消化并完全理解您提供的代码中的所有内容吗?
  • 好吧,如果你是一个有阅读欲望的菜鸟,我建议你改为学习 C#。 C# 更现代,并且有一些很棒的列表和集合类。
猜你喜欢
  • 2011-03-29
  • 1970-01-01
  • 1970-01-01
  • 2020-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-16
  • 2015-12-12
相关资源
最近更新 更多