# llListSortStrided

*LSL function*

```lsl
list list llListSortStrided(list src, integer stride, integer stride_index, integer ascending);
```

- `list src`: List to be sorted.
- `integer stride`: Number of entries per block/stride (defaults to 1 if less than 1).
- `integer stride_index`: Zero-based index of the element within each stride to use as the sort key (negatives count backward from the end of the stride).
- `integer ascending`: Boolean. If TRUE, sorts in ascending order; if FALSE, sorts in descending order.

- Returns: `list`
- Energy: 10

`llListSortStrided` is [llListSort](/functions/llListSort/) with the added parameter of **stride_index**, adding the flexibility to sort by any item in the **stride**. These routines use the same underlying code and have the same computational complexity.

Returns a [list](https://wiki.secondlife.com/wiki/list) that is **src** sorted by the **stride_index** item in every **stride**.

```lsl title="How to use" frame="terminal"
list result = llListSortStrided([], 0, 0, 0);
```

## Specification

The sort order is affected by type. For strings and keys, it is case sensitive and sorts by Unicode character code.

```lsl
llListSortStrided(["a", "á", "B", "C", "d", "e"], 1, 0, TRUE) // returns ["B", "C", "a", "d", "e", "á"]
```

For **ascending** sort, each type is sorted individually and then feathered to have the same order of types.

```lsl
llListSortStrided([1, "C", 3, "A", 2, "B"], 1, 0, TRUE) // returns [1, "A", 2, "B", 3, "C"]

llListSortStrided([1, 3, 2, "C", "A", "B"], 1, 0, TRUE) // returns [1, 2, 3, "A", "B", "C"]

llListSortStrided([1, "C", 3, "A", 2, "B"], 2, 0, TRUE) // returns [1, "C", 2, "B", 3, "A"]

llListSortStrided([1, "C", 3, "A", 2, "B"], 2, 1, TRUE) // returns [3, "A", 2, "B", 1, "C"]
```

## Caveats

- It uses the same unoptimized selection sort algorithm as [llListSort](/functions/llListSort/), which is an algorithm with a Big O of N². A [JIRA](https://wiki.secondlife.com/wiki/JIRA) issue exists to improve this function, [SVC-2988](https://jira.secondlife.com/browse/SVC-2988).
- Originally the wiki stated that non-zero values for the "**ascending**" parameter would produce an **ascending** sort. That was incorrect. For this function, the value must be exactly 1 (or [TRUE](/constants/TRUE/)) for an **ascending** sort.
- [Vector](https://wiki.secondlife.com/wiki/Vector)s are sorted by magnitude. [SVC-5643](https://jira.secondlife.com/browse/SVC-5643)
- [Rotation](https://wiki.secondlife.com/wiki/Rotation)s are not sorted in any meaningful order. If a list containing only rotations is sorted in **ascending** order, it will be returned unchanged.
- For descending sort, if there are mixed types, the final order is deterministic (the same input will always produce the same output) but it can be completely useless.

  ```lsl
  llListSortStrided([2, "B", "C", 3, 1, "A"], 1, 0, FALSE) // returns ["A", 3, 1, "C", "B", 2]
  ```

  If there are no mixed types, however, the descending sort works just fine.
- When the **stride** is greater than 1, if the list length is not a multiple of the **stride**, the list will be returned unchanged.
- **stride_index** must be less than **stride** and greater than or equal to -stride, otherwise an empty list is returned.
- When strings contain numbers, the numbers are still sorted left-to-right like any other character, which may not necessarily match numeric order:

  ```lsl
  llListSortStrided(["127", "3", "25"], 1, 0, TRUE) // returns ["127", "25", "3"] because the 1 in 127 is before the 2 in 25 which is before the 3
  ```

  To sort them in numeric order, numbers in strings can be padded with zeros:

  ```lsl
  llListSortStrided(["127", "003", "025"], 1, 0, TRUE) // returns ["003", "025", "127"]
  ```
- This order differs from the order of items in a prim's inventory, which is "natural order" (e.g "New Script 2" is sorted before "New Script 11").
- The sorting algorithm is not [stable](https://en.wikipedia.org/wiki/Sorting_algorithm#Stability). Thus you cannot use 2 sorts on different columns to sort by multiple keys:

  ```lsl
  default { state_entry() { // THIS DOES NOT WORK AS A MULTI-KEY SORT
      list input = [1, "b", 0, "c", 1, "a", 0, "b", 1, "c", 0, "a"];
      list partialSort = llListSortStrided(input, 2, 1, TRUE);
      llOwnerSay("partialSort = " + llList2Json(JSON_ARRAY, partialSort));
      list fullSort = llListSortStrided(partialSort, 2, 0, TRUE);
      llOwnerSay("fullSort = " + llList2Json(JSON_ARRAY, fullSort));
  } }
  ```

  This gives the following output (errors bolded):
- partialSort = \[1,"a",0,"a",**0,**"b",**1,**"b",**1,**"c",**0,**"c"\]
- fullSort = \[0,"a",0,"b",0,"c",1,**"b",**1,**"c",**1,**"a"**\]

## Examples

<details open>
<summary>Example 1</summary>

```lsl collapse={1-17}
list scoreboard =
    [ "Andrew", "Petersen", 200
    , "Jeremy", "Walker", 400
    , "Richard", "Baker", 100
    ];

default
{
    state_entry()
    {
        // Raw dump of the original, unsorted list

        llOwnerSay("Unsorted: scoreboard = [" + llDumpList2String(scoreboard, ",") + "]");
        // Result: [Andrew,Petersen,200,Jeremy,Walker,400,Richard,Baker,100]

        // Ascending (A to Z, 0 to 999)

        // Sort by first names (ascending)
        scoreboard = llListSortStrided(scoreboard, 3, 0, TRUE);
        llOwnerSay("Sort by first names (ascending) :: scoreboard = [" + llDumpList2String(scoreboard, ",") + "]");
        // Result: [Andrew,Petersen,200,Jeremy,Walker,400,Richard,Baker,100]

        // Sort by last names (ascending)
        scoreboard = llListSortStrided(scoreboard, 3, 1, TRUE);
        llOwnerSay("Sort by last names (ascending) :: scoreboard = [" + llDumpList2String(scoreboard, ",") + "]");
        // Result: [Richard,Baker,100,Andrew,Petersen,200,Jeremy,Walker,400]

        // Sort by score (ascending)
        scoreboard = llListSortStrided(scoreboard, 3, 2, TRUE);
        llOwnerSay("Sort by score (ascending) :: scoreboard = [" + llDumpList2String(scoreboard, ",") + "]");
        // Result: [Richard,Baker,100,Andrew,Petersen,200,Jeremy,Walker,400]

        // Descending (Z to A, 999 to 0)

        // Sort by first names (descending)
        scoreboard = llListSortStrided(scoreboard, 3, 0, FALSE);
        llOwnerSay("Sort by first names (descending) :: scoreboard = [" + llDumpList2String(scoreboard, ",") + "]");
        // Result: [Richard,Baker,100,Jeremy,Walker,400,Andrew,Petersen,200]

        // Sort by last names (descending)
        scoreboard = llListSortStrided(scoreboard, 3, 1, FALSE);
        llOwnerSay("Sort by last names (descending) :: scoreboard = [" + llDumpList2String(scoreboard, ",") + "]");
        // Result: [Jeremy,Walker,400,Andrew,Petersen,200,Richard,Baker,100]

        // Sort by score (descending)
        scoreboard = llListSortStrided(scoreboard, 3, 2, FALSE);
        llOwnerSay("Sort by score (descending) :: scoreboard = [" + llDumpList2String(scoreboard, ",") + "]");
        // Result: [Jeremy,Walker,400,Andrew,Petersen,200,Richard,Baker,100]
    }
}
```

</details>

<details>
<summary>[llListSort](/functions/llListSort/) and `llListSortStrided` really only works on items of the same type. It will work on lists that hold diverse data types -- to be clear, it won't blow up your script -- but the results returned are usually meaningless.</summary>

```lsl
list mylist = ["brown", <0.000000, 0.000000, 0.000000>, "house", 17.005, 100, "cat", <3.000000, 3.000000, 3.000000>, 39];
list tmplist = llListSortStrided(mylist, 1, 0, TRUE);
llSay(0, llList2CSV(tmplist));
```

</details>

<details>
<summary>This returns in chat:</summary>

brown, `<0.000000, 0.000000, 0.000000>`, cat, 17.004999, 39, house, `<3.000000, 3.000000, 3.000000>`, 100

The same ordered in descending order returns even more meaningless results:

```lsl
list mylist = ["brown", <0.000000, 0.000000, 0.000000>, "house", 17.005, 100, "cat", <3.000000, 3.000000, 3.000000>, 39];
list tmplist = llListSortStrided(mylist, 1, 0, FALSE);
llSay(0, llList2CSV(tmplist));
```

</details>

<details>
<summary>returns in chat:</summary>

39, `<3.000000, 3.000000, 3.000000>`, cat, 100, 17.004999, house, `<0.000000, 0.000000, 0.000000>`, brown

### Utilizing the Results

It's important to note that the source list that you are sorting will remain unchanged. Instead, a new, sorted list will be produced. So, it's important that you capture this with a variable (unless you are acting directly on the results.)

```lsl
llListSortStrided(myList, 1, 0, TRUE); // You've wasted cpu time; you didn't capture the results

list newlist = llListSortStrided(myList, 1, 0, TRUE);// Okay. You've captured the results.

llSay(0,llList2CSV(llListSortStrided(myList, 1, 0, TRUE))); // No need to capture, using the results right away.
```

</details>

<details>
<summary>Example 5</summary>

### `Stride` parameter

Most times, you will want to set "integer **stride**" to 1 (0 also works) to tell it to sort each item in the list on its own basis. (If you are working with a strided list, though, see the special section below on sorting strides.)

### Sort Order

Setting the parameter "integer **ascending**" to [TRUE](/constants/TRUE/) returns a sorted list that is in **ascending** order.

For example: \["Apples", "Bananas", "Oranges"\]

Setting the parameter "integer **ascending**" to [FALSE](/constants/FALSE/) returns a sorted list that is in descending order.

For example: \["Oranges", "Bananas", "Apples"\]

### Sorting Strided Lists

If you have a [strided list](https://wiki.secondlife.com/wiki/List#strided-lists), in which you are keeping related pieces of data together in chunks, letting each list element sort on its own basis would be disastrous.

```lsl
list demographics = ["John Adams", "male", "2007-06-22", "Shirley Bassey", "female", "2005-11-02", "Matt Damon", "male", "2008-05-19"];
```

</details>

<details>
<summary>Example 6</summary>

#### Bad Example

```lsl
list tmplist_1 = llListSortStrided(demographics, 1, 0, TRUE);
//tmplist_1 == ["2005-11-02", "2007-06-22", "2008-05-19", "John Adams", "Matt Damon", "Shirley Bassey", "female", "male", "male"]
//The strides have been destroyed, the sorted data is now useless
```

</details>

<details>
<summary>Example 7</summary>

#### Good Example

Instead, because you have the data grouped (aka "strided") in sets of 3, you need to do this:

```lsl
list tmplist_2 = llListSortStrided(demographics, 3, 0, TRUE);
//templist_2 = ["John Adams", "male", "2007-06-22", "Matt Damon", "male", "2008-05-19", "Shirley Bassey", "female", "2005-11-02"]
```

</details>

## Known issues

From the issue templates included by the wiki article:

- SVC-2988 (nf): Convert llListSort() to use faster sorting methods!
- SVC-5146 (nf): **llSortedListFindList**() - improved llListFindList() for known to be sorted lists

---

*Source: [LlListSortStrided](https://wiki.secondlife.com/wiki/LlListSortStrided) on the Second Life Wiki. Content from the Second Life Wiki articles LlListSortStrided (revision 1219163, 2026-10-03), Template:Issues/SVC-2988 (revision 1055222, 2010-10-07), Template:Issues/SVC-5146 (revision 1055252, 2010-10-07) and Template:LSL Function/stride (revision 1190281, 2014-05-03), CC BY-SA 3.0.*

---

From lsl.dev: https://lsl.dev/functions/llListSortStrided/
