Jump to content

logic question: comparing lists and sorting them


Xander Lopez
 Share

You are about to reply to a thread that has been inactive for 1396 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

I have a logic question.

Lets say I have the following lists.

list1 = ["uuid1", "A", 400];

list2 = ["uuid2", "B", 120];

list3 = ["uuid3", "B", 750];

list4 = ["uuid4", "A", 200];

list5 = ["uuid5", "C", 110];

list6 = ["uuid6", "A", 300];

 

First of all, I want to write a script that identifies all the Lists with "A" for the index 1.

So, the result would be:

list1 = ["uuid1", "A", 400];

list4 = ["uuid4", "A", 200];

list6 = ["uuid6", "A", 300];

 

And then, I would like to use the number in Index 2 to compare and sort them from highest to lowest.

list1 = ["uuid1", "A", 400];

list6 = ["uuid6", "A", 300];

list4 = ["uuid4", "A", 200];

 

And then, I would like to extract the index 0 and put them into a new list:

newlist = ["uuid1", "uuid6", "uuid4"]

 

Can anyone give me a concept on how I would approach this problem? I am familiar with the lsl syntax but here comes the real programming logic question.

Link to comment
Share on other sites

is a number of ways to do this

here is an example of one way

list list1 = ["uuid1", "A", 400];
list list2 = ["uuid2", "B", 120];
list list3 = ["uuid3", "B", 750];
list list4 = ["uuid4", "A", 200];
list list5 = ["uuid5", "C", 110];
list list6 = ["uuid6", "A", 300]; 

// as wrote sortstr assumes:
// list element 1 ("A") is a single char. If is variable length then append trailing spaces to make fixed-width
// list element 2 (400) is not greater than 1000
//  - convert to: 1000 - 400 = 600
//  - append leading "0" chars to make a fixed-width string 
// outputs
// "A0600" "B0880" "B0250" "A0800" C0890" "A0700" 
string sortstr(list s)
{
    return
        llList2String(s, 1) +
        llGetSubString("0000" + (string)(1000 - llList2Integer(s, 2)), -4, -1);
}

default
{
    state_entry()
    {
        // build a newlist from the 6 different lists
        list newlist;
        integer i;
        for (i = 1; i <= 6; i++)
        {
            // append sortstr, and its uuid as the 2nd element of newlist
            if (i == 1)
                newlist += [sortstr(list1), llList2String(list1, 0)];
            else if (i == 2)
                newlist += [sortstr(list2), llList2String(list2, 0)];
            else if (i == 3)
                newlist += [sortstr(list3), llList2String(list3, 0)];
            else if (i == 4)
                newlist += [sortstr(list4), llList2String(list4, 0)];
            else if (i == 5)
                newlist += [sortstr(list5), llList2String(list5, 0)];
            else
                newlist += [sortstr(list6), llList2String(list6, 0)];
        }

        // see LSL wiki for llListSort and llList2ListStrided
        newlist = 
            llList2ListStrided(
                llDeleteSubList(  // delete 1st element to align for ListStrided
                    llListSort(newlist, 2, TRUE),  // stride 2 sort
                0, 0),
            0, -1, 2);
       
        llOwnerSay(llDumpList2String(newlist, ","));
        // output should be:
        // uuid1,uuid6,uuid4,uuid3,uuid2,uuid5
    }
}

 

  • Like 2
Link to comment
Share on other sites

4 minutes ago, Mollymews said:

is a number of ways to do this

here is an example of one way

Neat solution but is the loop really needed? Couldn't you just do:

list newlist;
newlist += [sortstr(list1), llList2String(list1, 0)];
newlist += [sortstr(list2), llList2String(list2, 0)];
newlist += [sortstr(list3), llList2String(list3, 0)];
newlist += [sortstr(list4), llList2String(list4, 0)];
newlist += [sortstr(list5), llList2String(list5, 0)];
newlist += [sortstr(list6), llList2String(list6, 0)];

 

Edited by Wulfie Reanimator
  • Like 2
Link to comment
Share on other sites

even better Wulfie yes. I like!

building off what you have said then we can reduce it down to:

 list newlist = 
    llList2ListStrided(
       llDeleteSubList(  // delete 1st element to align for ListStrided
          llListSort(
          [ sortstr(list1), llList2String(list1, 0), 
            sortstr(list2), llList2String(list2, 0),
            sortstr(list3), llList2String(list3, 0),
            sortstr(list4), llList2String(list4, 0),
            sortstr(list5), llList2String(list5, 0),
            sortstr(list6), llList2String(list6, 0)
          ], 2, TRUE),  // stride 2 sort
       0, 0),
    0, -1, 2);

 

  • Like 2
Link to comment
Share on other sites

@Mollymews @Wulfie Reanimator Thanks for your advice.  But then, can I elaborate my questions a bit?

What if I would like to come up with 3 separate lists for A, B, C. (and 4 separate lists if there was a record of "D" too) So I can see something like:

(from highest number to lowest number)

newListForA would return.... uuid1,uuid6,uuid4

newListForB would return.... uuid3,uuid2

newListForC would return.... uuid5

 

So I think the trick is that I have to go through "Multiple Lists" to see which list has Value A, B or C.

 

 

Edited by Xander Lopez
Link to comment
Share on other sites

assuming this is some kind of gameplay ranking system then is usual to contain the players in a single strided list. Is more flexible/versatile when we do this

for example. sticking with the logic of using a sortstr:   (i haven't tested this and have just typed it off the top of my head so the typos may be variable)

list players = 
[
   "uuid1", "A", 400,
   "uuid2", "B", 120,
   "uuid3", "B", 750,
   "uuid4", "A", 200,
   "uuid5", "C", 110,
   "uuid6", "A", 300
]; 



// make a fixed-width string to sort on
string sortstr(list s)
{
   return
     llList2String(s, 0) +
     llGetSubString("0000" + (string)(1000 - llList2Integer(s, 1)), -4, -1);
}
   

// extract sublist by 'rank' and sort
// where 'rank' is the value of the 2nd stride element "A" "B" "C" "D" "E" etc  
list extractsort(string rank)
{
   // build the extract list
   list s;
   integer i;
   integer n = llGetListLength(players);
   for (i = 1; i < n; i += 3)  // stride 3 step, beginning with element 1
   {
      if (llList2String(players, i) == rank)
         s += [sortstr(llList2List(players, i, i + 1)), llList2String(players, i - 1)];
         // "A",400,"uuid1" -> "A0600","uuid1"  
   }   

   // return sorted extract list
   return
      llList2ListStrided(
         llDeleteSubList(  // delete 1st element to align for ListStrided
            llListSort(s, 2, TRUE),  // stride 2 sort
         0, 0),
      0, -1, 2);
}


// call 
list uuids = extractsort("A");

 

Edited by Mollymews
already saw a typo after I posted
  • Like 1
Link to comment
Share on other sites

18 hours ago, Xander Lopez said:

I wonder why I never thought of that before haha!

 

is lots of things I never think of either til somebody else has a look and goes what about this. Is how we learn from each other

and often we look again on being prompted by somebody else we can sometimes see how we can improve. Like looking at this again, we can make it a little more efficient by inlining the sortstr creation (removing a function call from within the loop). Example

s += [llList2String(players, 1) + llGetSubString("0000" + (string)(1000 - llList2Integer(players, 2)), -4, -1), llList2String(players, 0)];

 

edit correction: it should reference/offset 'i' and not absolute index values. Should be:

s += [llList2String(players, i) + llGetSubString("0000" + (string)(1000 - llList2Integer(players, i + 1)), -4, -1), llList2String(players, i - 1)];

 

Edited by Mollymews
Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 1396 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...