Jump to content

Strided List Oddity


Phil Deakins
 Share

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

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

Recommended Posts

I don't need a workaround for this, because I used a simple one, but I'd like to understand why I needed to do that.

At runtime, the script compiles a list in key-name pairs (key, name, key, name, key, name, etc.), and I need to get only the names into another list. Getting them with a strided list would be the obvious method, but it's not straight forward. The list can contain anything from 0 pairs to plenty of pairs. It's when there is only one pair (2 elements) that I hit the oddity. I.e. when the list length = the stride span.

list destination = llList2ListStrided(source_list, 1, -1, 2);  // 1 = element 1 (the name in the first pair), -1 = the end of list, and 2 = the stride span.

I tried all sort of things with the strided list to get the name out of the 1-pair list, but nothing worked. I tried going from end to beginning, and various start values. I tried using the actual list length instead of -1, and I even tried tried changing the -1 to a value greater than the length of the list. But nothing could entice that name out. All I could ever get out was the key - the 0 element.

Anyone got any ideas as to why it didn't work?

(I can't reverse the order to name-key pairs without getting messy later on, because the script will be sorting on keys later. And it may not succeed, anyway.)

Edited by Phil Deakins
Link to comment
Share on other sites

The secret is to use llDeleteSubList, where we slice out from the original.

Example:

list listOriginal = [1, "Ms. Smith"];

// example with more elements

// list listOriginal = [1, "Ms. Smith", 2, "Mr. Smith", 3, "Doc. Jones", 4, "Nurse Jones"];

default
{
    state_entry()
    {
    }

    touch_start(integer total_number)
    {
        //stride of 2
        list listResult = llList2ListStrided(llDeleteSubList(listOriginal, 0, 0), 0, -1, 2);
        
        // Dump content
        integer i;
        integer length = llGetListLength(listResult);
        do
            llOwnerSay(llList2String(listResult, i) );
        while(++i < length);        
    }
}

 

 

  • Thanks 1
Link to comment
Share on other sites

18 minutes ago, Rachel1206 said:

The secret is to use llDeleteSubList, where we slice out from the original.

Example:

list listOriginal = [1, "Ms. Smith"];

// example with more elements

// list listOriginal = [1, "Ms. Smith", 2, "Mr. Smith", 3, "Doc. Jones", 4, "Nurse Jones"];

default
{
    state_entry()
    {
    }

    touch_start(integer total_number)
    {
        //stride of 2
        list listResult = llList2ListStrided(llDeleteSubList(listOriginal, 0, 0), 0, -1, 2);
        
        // Dump content
        integer i;
        integer length = llGetListLength(listResult);
        do
            llOwnerSay(llList2String(listResult, i) );
        while(++i < length);        
    }
}

If I'm reading that correctly, Rachel, it removes the names from my source list - and yours - but I don't want them deleted from the source. I just want to create a new list comprising every 2nd element in the source list, but without affecting the source list.

Edited by Phil Deakins
Link to comment
Share on other sites

default
{    state_entry()
    {
    }
    touch_start(integer total_number)
    { list num = [0,1,2,3,4,5,6,7,8,9,10,11] ;        
      list names =  llDeleteSubList(num,0,0);
      names =  llList2ListStrided(llList2List(names, 0, -1), 0, -1, 2);  
      string tmp = llDumpList2String(names," , ");
      llOwnerSay(" list is " + tmp);
      
    }
}

or something...?

  • Thanks 1
Link to comment
Share on other sites

:) almost but not quite.

A list's numbering starts at element 0. So starting at 1 means starting at the 2nd element in the list. In my list that would be the name element.

-1 mean the end of the list.

The 2 is the stride span.

So llList2ListStrided(1, -1, 2) means only deal with the part of the list that starts at element 1 and finishes at the end of the list. And only get the every second element (the stride span). In other words all of the source list but starting at element 1 and not element 0. Starting at element 0 would return the data that's in that element - in my case it's a key, and I don't want that.

Link to comment
Share on other sites

17 minutes ago, Phil Deakins said:

If I'm reading that correctly, Rachel, it removes the names from my source list - and yours - but I don't want them deleted from the source. I just want to create a new list comprising every 2nd element in the source list, but without affecting the source list.

I don't think so. Rather, llDeleteSubList() creates a new source list that skips over that 0th element (the very first key), and from that llList2ListStrided() can do what it does: returning the first element of each stride (now the names instead of the keys).

Just guessing, but one popular confusion is mistaking llDeleteSubList() for affecting the list on which it's called. Rather, to get that effect, that original list variable must be explicitly assigned to the result of the function.

I haven't actually run it, so you may want to make sure it doesn't do anything stupid when the original source list is empty.

Link to comment
Share on other sites

Aha! I tried it and it works. Thanks go to both Rachel and Xiija :)

@Qie Niangao  Of course. I knew that and it does make sense, but I didn't think of it when I read the posted scripts. Thank you :)

It's a bit of a daft thing, having to do that sort of thing though when llList2ListStrided() ought to do it without any help. I don't understand why it's necessary. I'm used to using that function, but maybe my previous uses of it have always started at the beginning of a list.

Edited by Phil Deakins
Link to comment
Share on other sites

29 minutes ago, Love Zhaoying said:

So now, I’m confused as to your question. The same logic applies even if there are 1 or N entries in your strides list.

My logic was that I could start where I tell it to start and get every nth element from there. So the first element would come from my starting point.

I don't understand why it didn't work, because the function requires a starting point, which means that it doesn't have to always start at the beginning of a list. The script snippets in this thread, arrange to start at the beginning of a list, so I'm confused.

Link to comment
Share on other sites

It's not like that. Suppose you have a list of 20 elements (0 - 19), and you want every 4th element (3, 7, 11, 15, 19), the stride is 4, and you'd get elements 3, 7, 11, 15, and 19. It has nothing to do with the elements within a stride. They aren't accessed at all.

In my case, I wanted the every 2nd element of a 2-element list (elements 0 and 1). So I set the stride to start at 1 (the 2nd element) and finish when it reached the end of the list, which is also the 2nd element. It should do it, but it doesn't. If the list had had 4 elements (0, 1, 2 and 3), with the same starting element 1 and go to the end, it should return elements 1 and 3.

Edited by Phil Deakins
Link to comment
Share on other sites

It's a good catch Phil :)

Someone should make a note in the wiki....

if start & end both point to the same list item, the function apparently has NO operating range ?

       list mylist = [0,1];
       list result_a = llList2ListStrided(mylist,1,-1,2);   ( or ... llList2ListStrided(mylist,1,1,2);    )

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 2209 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...