Forum Discussion

mcbootus's avatar
mcbootus
Contributor
15 years ago

Sorting multiple lists by a list item

Dear all,

I have 5 lists which are formatted identically and the third item in each list is a date and time. Like so:

myList1 [1,4,12MAR2011T14:33,4,6]
myList2 [3,2,12MAR2011T14:20,4,6]
myList3 [2,7,16JUN2011T14:42,4,6]
myList4 [5,1,21MAR2011T18:20,4,6]
myList5 [6,5,09MAR2011T14:20,4,6]


What would be the easiest way to contain these lists in an array and then reorder the lists by date so the output would be:


myList5 [6,5,09MAR2011T14:20,4,6]
myList2 [3,2,12MAR2011T14:20,4,6]
myList1 [1,4,12MAR2011T14:33,4,6]
myList4 [5,1,21MAR2011T18:20,4,6]
myList3 [2,7,16JUN2011T14:42,4,6]



Many thanks in advance,
Armen

10 Replies

  • I would appreciate some help on this!

    Thanks in advance.
    Armen
  • Dear Henrik,

    Thank you for your assistance.

    Yes they are groovy lists created like this:

    a = testRunner.testCase.testSteps["PropertiesXML"].getPropertyValue("block number")
    b = testRunner.testCase.testSteps["PropertiesXML"].getPropertyValue("code")
    c = testRunner.testCase.testSteps["PropertiesXML"].getPropertyValue("eventDateTime")
    d = testRunner.testCase.testSteps["PropertiesXML"].getPropertyValue("comment")
    e = testRunner.testCase.testSteps["PropertiesXML"].getPropertyValue("transmissionStatus")
    f = testRunner.testCase.testSteps["PropertiesXML"].getPropertyValue("transmissionVersion")

    myList = [a,b,c,d,e,f]


    I believe the date is a string just grabbed via XPath from the XML output - I may need to parse the date (or convert it to a date datatype) to compare it with the Database value properly - but for now its a string.


    Maybe it is easier to drop the list coding entirely and to create and array where each pass of the loop stores the 6 values into a row of the array, and then to rearrange the rows that way?


    Thanks again,
    Armen
  • This should do the trick (the results go into sortedMasterArray):

    import java.text.SimpleDateFormat

    // Returns and removes the list with the lowest/earliest Date from myArray
    def extractFirstOrdered( myArray )
    {
    firstOrdered = null
    for( list in myArray )
    {
    if( firstOrdered == null || list[2] < firstOrdered[2] )
    firstOrdered = list
    }
    myArray.remove( firstOrdered )
    return firstOrdered
    }

    a = [1,4,"12MAR2011T14:33",4,6]
    b = [3,2,"12MAR2011T14:20",4,6]
    c = [2,7,"16JUN2011T14:42",4,6]
    d = [5,1,"21MAR2011T18:20",4,6]
    e = [6,5,"09MAR2011T14:20",4,6]

    def masterArray = [a, b, c, d, e]

    SimpleDateFormat dateParser = new SimpleDateFormat("ddMMMyyyy'T'HH:mm")

    // Convert date strings to Date objects
    for( list in masterArray )
    {
    list[2] = dateParser.parse( list[2] )
    }

    // Sort masterArray
    def sortedMasterArray = []
    while( !masterArray.isEmpty() )
    {
    sortedMasterArray.add( extractFirstOrdered( masterArray ) )
    }


    /Henrik
    http://www.eviware.com
  • Dear Henrik,

    Thank you very much for your code - it works very well - but I forgot to mention that the collection of the list happens one at a time via an incremental loop which collects the data on one pass then increments the XPath[] to collect the next block - so on every loop step we need to pass the list data into the array.



    In our scenario we have created a loop which calls the property transfer to populate the list - so on each pass of the loop one list is created like so:

    // loop the number of tag blocks - where r is the number of blocks which is determined by an XPath count (1-500 subtag blocks)
    while( x < Integer.parseInt(r) ){
    x++

    // increment the block number to test each subtag block - this increments the Xpath [] to collect each block of data
    testRunner.testCase.getTestStepByName('PropertiesXML').setPropertyValue("block number","${x}")

    // Run the write to XML routine to write XML values to the properties file - this collects the data from the WS XML via XPath
    testRunner.runTestStepByName("Write to XML")

    // The Xpath values are stored in the properties file
    a = testRunner.testCase.testSteps["PropertiesXML"].getPropertyValue("block number")
    b = testRunner.testCase.testSteps["PropertiesXML"].getPropertyValue("code")
    c = testRunner.testCase.testSteps["PropertiesXML"].getPropertyValue("eventDateTime")
    d = testRunner.testCase.testSteps["PropertiesXML"].getPropertyValue("comment")
    e = testRunner.testCase.testSteps["PropertiesXML"].getPropertyValue("transmissionStatus")
    f = testRunner.testCase.testSteps["PropertiesXML"].getPropertyValue("transmissionVersion")

    // The Xpath values are taken from the properties file to create a list
    myList = [a,b,c,d,e,f]

    // Add the myList to the Master array in block x
    xxxxxxxxx


    }


    As you can see, on each pass of the loop I need to add the myList to an array - and since the number of list blocks is random (1-500 blocks) we have to create a dynamic array to account for the blocks - then we can collect all the block data before executing the sorting of the dates.


    How can I add each myList loop step to the array in position x please?

    Many thanks for your excellent help!

    Armen
  • If I understand you correctly, you probably want to do something like this:
    // loop the number of tag blocks - where r is the number of blocks which is determined by an XPath count (1-500 subtag blocks)
    def masterArray = []
    while( x < Integer.parseInt(r) ){
    x++

    // increment the block number to test each subtag block - this increments the Xpath [] to collect each block of data
    testRunner.testCase.getTestStepByName('PropertiesXML').setPropertyValue("block number","${x}")

    // Run the write to XML routine to write XML values to the properties file - this collects the data from the WS XML via XPath
    testRunner.runTestStepByName("Write to XML")

    // The Xpath values are stored in the properties file
    a = testRunner.testCase.testSteps["PropertiesXML"].getPropertyValue("block number")
    b = testRunner.testCase.testSteps["PropertiesXML"].getPropertyValue("code")
    c = testRunner.testCase.testSteps["PropertiesXML"].getPropertyValue("eventDateTime")
    d = testRunner.testCase.testSteps["PropertiesXML"].getPropertyValue("comment")
    e = testRunner.testCase.testSteps["PropertiesXML"].getPropertyValue("transmissionStatus")
    f = testRunner.testCase.testSteps["PropertiesXML"].getPropertyValue("transmissionVersion")

    // The Xpath values are taken from the properties file to create a list
    def myList = [a,b,c,d,e,f]

    // Add the myList to the Master array in block x
    masterArray.add( myList )

    }

    Good luck!

    /Henrik
  • Dear Henrik,

    Perfect! Thank you very much for your assistance - that works really well.

    Thanks for the great support!

    Armen
  • Dear Henrik,

    Thanks for your code - everything is working fine on the sort but now I have a situation where more than one array column needs to be sorted, first the date then another value. I dont understand the top section pasted below - it seems that this code only works with sorting one property. But I cannot re-use it again to sort something else. What confuses me is this code doesn't point to a specific array and rather its generic - I have a "masterArray" to arrange by date and then I have another column in another array called "dbArray" where I need to arrange by "ID number".

    // Returns and removes the list with the lowest/earliest Date from myArray
    def extractFirstOrdered( myArray )
    {
    firstOrdered = null
    for( list in myArray )
    {
    if( firstOrdered == null || list[2] < firstOrdered[2] )
    firstOrdered = list
    }
    myArray.remove( firstOrdered )
    return firstOrdered
    }


    How can I make this code sort specific arrays by name rather than generically ?

    Thanks again for your help.

    Armen
  • Hi Armen,

    The expression list[2] means "the element with index 2 in the array list", which is the date column in your first question (indexing of arrays start with 0 in most programming languages -- e.g. the third element has index 2). So
    if (list[2] < firstOrdered[2]) 
    means "if the date in list is smaller/earlier than the date in firstOrdered".

    Changing the number two to something else would be a good start. You might even want to make it an argument to the function, something like this:

    /*
    * Sorts the sub arrays in myArray based on comparison of the n:th element in the sub arrays.
    *
    * @param myArray The array which contains the sub arrays.
    * @param n The index of the element to sort the sub arrays by.
    */
    def extractFirstOrdered( myArray, n )
    {
    firstOrdered = null
    for( list in myArray )
    {
    if( firstOrdered == null || list[n] < firstOrdered[n] )
    firstOrdered = list
    }
    myArray.remove( firstOrdered )
    return firstOrdered
    }
  • Dear Henrik,

    Perfect! It works really good - and now I understand the code aswell.

    Thank you again for your great assistance.

    Best regards,
    Armen