Sorting a collection in classic ASP

2019-02-03 16:43发布

It's quite a simple question - how do I sort a collection?

I've got a CSV file with rows in a random order. I'd like to sort the rows according to the date in one column. Do I add the rows to a recordset? Can I sort with a Scripting.Dictionary?

I've clearly been spoilt with .NET and Linq, and now I find myself back in the land of classic asp, realising I must have known this 7 years ago, and missing generics immensely. I feel like a complete n00b.

5条回答
Rolldiameter
2楼-- · 2019-02-03 16:57

In this case I would get help from big brother .net. It's possible to use System.Collections.Sortedlist within your ASP app and get your key value pairs sorted.

set list = server.createObject("System.Collections.Sortedlist")
with list
  .add "something", "YY"
  .add "something else", "XX"
end with

for i = 0 to list.count - 1
    response.write(list.getKey(i) & " = " & list.getByIndex(i))
next

Btw if the following .net classes are available too:

  • System.Collections.Queue
  • System.Collections.Stack
  • System.Collections.ArrayList
  • System.Collections.SortedList
  • System.Collections.Hashtable
  • System.IO.StringWriter
  • System.IO.MemoryStream;

Also see: Marvels of COM .NET interop

查看更多
地球回转人心会变
3楼-- · 2019-02-03 17:08

I'd go with the RecordSet approach. Use the Text Driver. You'll need to change the directory in the connection string and the filename in the select statement. the Extended Property "HDR=Yes" specifies that there's a header row in the CSV which I suggest as it will make writing the psuedo SQL easier.

<%

Dim strConnection, conn, rs, strSQL

strConnection = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\inetpub\wwwroot\;Extended Properties='text;HDR=Yes;FMT=Delimited';"

Set conn = Server.CreateObject("ADODB.Connection")
conn.Open strConnection

Set rs = Server.CreateObject("ADODB.recordset")
strSQL = "SELECT * FROM test.csv order by date desc"
rs.open strSQL, conn, 3,3

WHILE NOT rs.EOF
    Response.Write(rs("date") & "<br/>") 
    rs.MoveNext
WEND

rs.Close
Set rs = Nothing

conn.Close
Set conn = Nothing

%>
查看更多
何必那么认真
4楼-- · 2019-02-03 17:12

A late late answer to this, but still of value.

I was working with small collections so could afford the approach where I inserted the item in the correct place on each occasion, effectively reconstructing the collection on each addition.

The VBScript class is as follows:

'Simple collection manager class.
'Performs the opration of adding/setting a collection item.
'Encapulated off here in order to delegate responsibility away from the collection class.
Class clsCollectionManager
    Public Sub PopulateCollectionItem(collection, strKey, Value)
        If collection.Exists(strKey) Then
            If (VarType(Value) = vbObject) Then
                Set collection.Item(strKey) = Value
            Else
                collection.Item(strKey) = Value
            End If
        Else
            Call collection.Add(strKey, Value)
        End If
    End Sub

    'take a collection and a new element as input parameters, an spit out a brand new collection 
    'with the new item iserted into the correct location by order
    'This works on the assumption that the collection it is receiving is already ordered 
    '(which it should be if we always use this method to populate the item)

    'This mutates the passed collection, so we highlight this by marking it as byref 
    '(this is not strictly necessary as objects are passed by reference anyway)
    Public Sub AddCollectionItemInOrder(byref existingCollection, strNewKey, Value)
        Dim orderedCollection: Set orderedCollection = Server.CreateObject("Scripting.Dictionary")
        Dim strExistingKey

        'If there is something already in our recordset then we need to add it in order.

        'There is no sorting available for a collection (or an array) in VBScript. Therefore we have to do it ourself.
        'First, iterate over eveything in our current collection. We have to assume that it is itself sorted.
        For Each strExistingKey In existingCollection

            'if the new item doesn't exist AND it occurs after the current item, then add the new item in now 
            '(before adding in the current item.)
            If (Not orderedCollection.Exists(strNewKey)) And (strExistingKey > strNewKey) Then
                Call PopulateCollectionItem(orderedCollection, strNewKey, Value)
            End If
            Call PopulateCollectionItem(orderedCollection, strExistingKey, existingCollection.item(strExistingKey))
        Next

        'Finally check to see if it still doesn't exist. 
        'It won't if the last place for it is at the very end, or the original collection was empty
        If (Not orderedCollection.Exists(strNewKey)) Then
            Call PopulateCollectionItem(orderedCollection, strNewKey, Value)
        End If

        Set existingCollection = orderedCollection
    End Sub
End Class
查看更多
一夜七次
5楼-- · 2019-02-03 17:15

It's been a long time for me too. IIRC you don't have an option out of the box.

If I were you I'd put all the data in an array and then sort the array. I found a QuickSort implementation here: http://www.4guysfromrolla.com/webtech/012799-3.shtml

查看更多
时光不老,我们不散
6楼-- · 2019-02-03 17:17

Also look at the "Bubble Sort", works excellent with those classic asp tag cloud.

http://www.4guysfromrolla.com/webtech/011001-1.shtml

查看更多
登录 后发表回答