【问题标题】:VBScript to sort lines in a fileVBScript对文件中的行进行排序
【发布时间】:2013-01-28 13:59:49
【问题描述】:

我正在尝试使用 VBScript (MS Internet Explorer) 对文件中的行进行排序。基本上我读取了文件并将所有行转换为一个数组。基本上我需要对每行字符 23 和 27 之间写的任何内容进行排序。所以基本上我可以使用MID 获取这些字符。这些字符不是每行唯一的(所以我不能直接使用System.Collections.Sortedlist,或者不幸的是类似的东西)。

我可以使用System.Collections.Sortedlist 并使用 23 和 27 之间的字符作为键,并使用另一个 System.Collections.Sortedlist 对象作为值,填充每个唯一值(因此是二维数组),但是这会是正确的方法吗?例如:

(System.Collections.Sortedlist) {
    "0001" => (System.Collections.Sortedlist) {
        0 => "0001 some unique value1"
        1 => "0001 some unique value2"
        2 => "0001 some unique value3"
    },
    "0002" => (System.Collections.Sortedlist) {
        0 => "0002 some unique value1"
        1 => "0002 some unique value2"
        2 => "0002 some unique value3"
    }
}

有没有更好的方法来处理这个问题? 还要注意输出格式应该是数组。

【问题讨论】:

  • VBScript?在 IE 中?我是否陷入了时间扭曲,又回到了 2001 年?
  • 好吧..客户端使用它。并从那开始一年。我目前正在使用win2k机器。快得要命,但真的很精简。我什至无法安装 .NET 3.5 框架..
  • 哇,这听起来像是网络开发者的特殊版本的地狱。我敢打赌他们也被困在 IE6 上,对吧?如果你已经有了工作代码,我建议使用它;不要担心找到更好的方法来做到这一点;无论如何,客户显然对最佳实践不感兴趣。
  • @JvN - 看这里:stackoverflow.com/a/13758037/603855 了解如何使用断开连接的记录集或 .Net 集合(以及一些额外的工作)。
  • @Ekkehard.Horner - 嗯。这看起来像一个不错的对象。谢谢!

标签: sorting vbscript


【解决方案1】:

作为预告片(另见ArrayListDisconnected Recordset and ArrayList):

  Dim aTest : aTest = Array( _
      ". Z 0" _
    , ", B 2" _
    , "? A 1" _
  )
  WScript.Echo "----- ArrayList"
  WScript.Echo "original data:     ", "[""" & Join(aTest                          , """  """) & """]"
  WScript.Echo "AL:  (full)        ", "[""" & Join(sortAL(aTest)                  , """  """) & """]"
  WScript.Echo "AL:  (numerical)   ", "[""" & Join(sortAL(Array(12, 9, -1))       , """  """) & """]"
  WScript.Echo "AL:  (dates)       ", "[""" & Join(sortAL(Array(Now + 5, Now - 5)), """  """) & """]"
  WScript.Echo "AL:  (Mid(elm,3,1))", "[""" & Join(sortAL_31(aTest)               , """  """) & """]"
  WScript.Echo "----- Disconnected Recordset"
  WScript.Echo "DRS: (Mid(elm,3,1))", "[""" & Join(sortDRS_Substring(aTest, 3, 1) , """  """) & """]"
  WScript.Echo "DRS: (Mid(elm,5,1))", "[""" & Join(sortDRS_Substring(aTest, 5, 1) , """  """) & """]"

' ArrayList.Sort handles homogenous arrays of simple types just fine,
' but looks at the element in full. For other cases, you need extra work
' or ADO
Function sortAL(aX)
  Dim al : Set al = CreateObject("System.Collections.ArrayList")
  Dim elm
  For Each elm In aX
      al.Add elm
  Next
  al.Sort
  sortAL = al.ToArray()
End Function

' Extra work: feeding pre-processed data to the ArrayList; hardcoded
Function sortAL_31(aX)
  Const csSep = ":"
  Dim al : Set al = CreateObject("System.Collections.ArrayList")
  ReDim a(UBound(aX))
  Dim elm
  For Each elm In aX
      al.Add Mid(elm, 3, 1) & csSep & elm
  Next
  al.Sort
  For elm = 0 To UBound(a)
      a(elm) = Split(al(elm), csSep)(1)
  Next
  sortAL_31 = a
End Function

' more flexible: ADO DRS + a start at parametrization; handling different
' types is left as an exercise
Function sortDRS_Substring(aX, nFrom, nLen)
  Const adVarChar    = 200 ' 000000C8
  Const adClipString =   2 ' 00000002
  Const csSep        = ":"
  ReDim a(Ubound(aX))
  Dim oRS : Set oRS = CreateObject("ADODB.Recordset")
  oRS.Fields.Append "FORG", adVarChar, 250
  oRS.Fields.Append "FSUB", adVarChar, 250
  oRS.Open
  Dim elm
  For Each elm In aX
      oRS.AddNew
      oRS.Fields("FORG").value = elm
      oRS.Fields("FSUB").value = Mid(elm, nFrom, nLen)
      oRS.UpDate
  Next
  oRS.Sort = "FSUB"
  oRS.MoveFirst
  For elm = 0 To UBound(a)
      a(elm) = oRS.Fields("FORG").value
      oRS.MoveNext
  Next
  sortDRS_Substring = a
End Function

输出:

----- ArrayList
original data:      [". Z 0"  ", B 2"  "? A 1"]
AL:  (full)         [", B 2"  ". Z 0"  "? A 1"]
AL:  (numerical)    ["-1"  "9"  "12"]
AL:  (dates)        ["1/23/2013 5:00:22 PM"  "2/2/2013 5:00:22 PM"]
AL:  (Mid(elm,3,1)) ["? A 1"  ", B 2"  ". Z 0"]
----- Disconnected Recordset
DRS: (Mid(elm,3,1)) ["? A 1"  ", B 2"  ". Z 0"]
DRS: (Mid(elm,5,1)) [". Z 0"  "? A 1"  ", B 2"]

【讨论】:

    【解决方案2】:

    我想建议的功能和Ekkehard Horner的sortAL_31几乎一样。

    Function CustomSort(ByVal inpArray, ByVal nFrom, ByVal nLen)
        Dim oList, aTmp(), nSize, i
        nSize = UBound(inpArray)
        ReDim aTmp(nSize)
        With CreateObject("System.Collections.ArrayList")
            For i = 0 To nSize
                .Add Mid(inpArray(i), nFrom, nLen) & _
                    vbNullChar & inpArray(i)
            Next
            .Sort
            For i = 0 To nSize
                aTmp(i) = Split(.Item(i), vbNullChar)(1)
            Next
        End With
        CustomSort = aTmp
    End Function
    

    [编辑] 使用SortedList 附加版本。

    Function CustomSort2(inpArray, nFrom, nLen)
        Dim oSList, aTmp(), nSize, i
        nSize = UBound(inpArray)
        ReDim aTmp(nSize)
        Set oSList = CreateObject("System.Collections.SortedList")
        For i = 0 To nSize
            oSList.Add Mid(inpArray(i), nFrom, nLen), inpArray(i)
        Next
        For i = 0 To nSize
            aTmp(i) = oSList.GetByIndex(i)
        Next
        Set oSList = Nothing
        CustomSort2 = aTmp
    End Function
    

    【讨论】:

    • 我喜欢的(+1.3):使用 vbNullChar 作为分隔符;我不喜欢什么(-0.2):aTmp() 是 VBScript 外来的 VB/VBA 习语(尝试获取它的 UBound());我不会做什么(-0.05):在任何参数上使用 ByVal - 特别是 inpArray 的副本没有意义。
    • 谢谢,感谢您的评论。至于 aTmp() 我真的不明白你的意思。我只是尝试将对 UBound() 的调用减少到一次。或者您的意思是省略 Dim aTmp() 并直接使用 ReDim aTmp(nSize)?
    • 是的,“Dim aTmp()”创建了一个 VBScript 甚至 UBound() 都无法做到的可恶;一个普通的“ReDim aTmp()”就足够了(即使是“Option Explicit”)。
    猜你喜欢
    • 1970-01-01
    • 2013-06-06
    • 1970-01-01
    • 2013-02-10
    • 1970-01-01
    • 1970-01-01
    • 2015-02-26
    • 2013-05-15
    • 2011-10-15
    相关资源
    最近更新 更多