Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

A Little List Advice

Nyx Alsop
Registered User
Join date: 14 Dec 2008
Posts: 252
12-14-2009 16:20
I'm making something that registers names into a list, many will be and should be duplicate.

What I need to do is find out how many of each name is in the list.

Say in list we have:

"apple", "apple", "orange", "orange", "orange", "orange", "orange", "orange", "orange", "orange";

What's the most efficent way to find how many times orange appears in the list? it will be a dynamic but not static value.
Argent Stonecutter
Emergency Mustelid
Join date: 20 Sep 2005
Posts: 20,263
12-14-2009 16:35
From: Nyx Alsop
I'm making something that registers names into a list, many will be and should be duplicate.

What I need to do is find out how many of each name is in the list.

Say in list we have:

"apple", "apple", "orange", "orange", "orange", "orange", "orange", "orange", "orange", "orange";

What's the most efficent way to find how many times orange appears in the list? it will be a dynamic but not static value.
I think stepping through it would avoid making extra copies of the list, which would be expensive:

int i = llListFindList(i, "orange";); // find first

if (i == -1) return 0;

int n = llGetListLength(l);
int c = 1;

while(++i < n) // preincrement, so we step over first match and step through to end
if(llList2String(l, i) == "orange";) c++;

return c;
_____________________
Argent Stonecutter - http://globalcausalityviolation.blogspot.com/

"And now I'm going to show you something really cool."

Skyhook Station - http://xrl.us/skyhook23
Coonspiracy Store - http://xrl.us/coonstore
Lazink Maeterlinck
Registered User
Join date: 8 Nov 2005
Posts: 332
12-14-2009 20:07
If memory isn't your main concern, sort the list, then find do a search for the first implementation of orange, then step through the list until you find that it isn't orange anymore, but Agent's way is most likely your best route in what you want.
Sindy Tsure
Will script for shoes
Join date: 18 Sep 2006
Posts: 4,103
12-14-2009 20:55
From: Lazink Maeterlinck
If memory isn't your main concern, sort the list, then find do a search for the first implementation of orange, then step through the list until you find that it isn't orange anymore..

This sounds faster to me...
_____________________
Sick of sims locking up every time somebody TPs in? Vote for SVC-3895!!!
- Go here: https://jira.secondlife.com/browse/SVC-3895
- If you see "if you were logged in.." on the left, click it and log in
- Click the "Vote for it" link on the left
Argent Stonecutter
Emergency Mustelid
Join date: 20 Sep 2005
Posts: 20,263
12-14-2009 21:18
llListSort is a bubble sort. :(

My suggestion is O(N), llListSort is O(n*n).
_____________________
Argent Stonecutter - http://globalcausalityviolation.blogspot.com/

"And now I'm going to show you something really cool."

Skyhook Station - http://xrl.us/skyhook23
Coonspiracy Store - http://xrl.us/coonstore
Angela Talamasca
VR Hacks
Join date: 20 Feb 2007
Posts: 58
12-14-2009 22:48
Why not set up a strided list and simply increment the count, each time you add an identical name? So, from your example, you would have:

list fruits = ["apple", 2, "orange", 7];

function add(string item){
integer idx = llListFindList[fruits,[item]) + 1;
if(idx < 1){
fruits = (fruits = []) + fruits + [item, 1];
}else{
integer cnt = llList2Integer(fruits,idx) + 1;
fruits = llListReplaceList(fruits, [cnt], idx, idx);
}
}

integer function getCount(string item){
integer idx = llListFindList[fruits,[item]) + 1;
if(idx > 0){
return llList2Integer(fruits,idx);
}
return -1;
}

To add an "apple" you could then simply call add("apple";);

And, to get your item count, you simply call getCount("apple";);

An impl such as the above, trumps unnecessary resource intensive looping and reduces memory reqs. In other words, you've just reduced your list memory from 42 bytes to 13 bytes. And, if you add more apples and oranges, you're still only looking at 13 bytes. If you add a "banana" or whatever, the list memory will increase by the number of characters pls, one byte, at the very least.
_____________________

Blog: http://blog.vrhacks.net
AUSL: http://www.avatarsunited.com/avatars/angela-talamasca
AUBM: http://www.avatarsunited.com/avatars/angela-talamasca-blue-mars
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
12-15-2009 01:20
or you could parse the list to a string, with a separator, parse it back to a list removing both the separators and the specific item, then count the difference.
_____________________
|
| . "Cat-Like Typing Detected"
| . This post may contain errors in logic, spelling, and
| . grammar known to the SL populace to cause confusion
|
| - Please Use PHP tags when posting scripts/code, Thanks.
| - Can't See PHP or URL Tags Correctly? Check Out This Link...
| -
Lazink Maeterlinck
Registered User
Join date: 8 Nov 2005
Posts: 332
12-15-2009 17:09
From: Argent Stonecutter
llListSort is a bubble sort. :(

My suggestion is O(N), llListSort is O(n*n).


You sure it's a bubble sort? Wouldn't surprise me if it was, but a pivot sort isn't that hard to implement for any programmer. There is a big difference between O(nlog n) vs O(n^2), but then again, in SL you aren't dealing with that big of lists to make huge differences.
Argent Stonecutter
Emergency Mustelid
Join date: 20 Sep 2005
Posts: 20,263
12-15-2009 17:29
From: Lazink Maeterlinck
You sure it's a bubble sort?
That's what the wiki claims.
_____________________
Argent Stonecutter - http://globalcausalityviolation.blogspot.com/

"And now I'm going to show you something really cool."

Skyhook Station - http://xrl.us/skyhook23
Coonspiracy Store - http://xrl.us/coonstore
Sindy Tsure
Will script for shoes
Join date: 18 Sep 2006
Posts: 4,103
12-15-2009 17:33
I thought mono lists were ArrayList objects.. Google says:
From: someone
This method uses Array..::.Sort, which uses the QuickSort algorithm. The QuickStort algorithm is a comparison sort (also called an unstable sort), which means that a "less than or equal to" comparison operation determines which of two elements should occur first in the final sorted list. However, if two elements are equal, their original order might not be preserved. In contrast, a stable sort preserves the order of elements that are equal. To perform a stable sort, you must implement a custom IComparer interface to use with the other overloads of this method.

On average, this method is an O(n log n) operation, where n is Count; in the worst case it is an O(n^2) operation.
_____________________
Sick of sims locking up every time somebody TPs in? Vote for SVC-3895!!!
- Go here: https://jira.secondlife.com/browse/SVC-3895
- If you see "if you were logged in.." on the left, click it and log in
- Click the "Vote for it" link on the left
Argent Stonecutter
Emergency Mustelid
Join date: 20 Sep 2005
Posts: 20,263
12-15-2009 18:42
The semantics of LSL sorting are a little odd, particularly when lists contain elements of different types, and I suspect that they aren't using a standard sort operator.
_____________________
Argent Stonecutter - http://globalcausalityviolation.blogspot.com/

"And now I'm going to show you something really cool."

Skyhook Station - http://xrl.us/skyhook23
Coonspiracy Store - http://xrl.us/coonstore
Nyx Alsop
Registered User
Join date: 14 Dec 2008
Posts: 252
12-15-2009 19:28
It's a dynamtic list I wont know any values to start with.



From: Angela Talamasca
Why not set up a strided list and simply increment the count, each time you add an identical name? So, from your example, you would have:

list fruits = ["apple", 2, "orange", 7];

function add(string item){
integer idx = llListFindList[fruits,[item]) + 1;
if(idx < 1){
fruits = (fruits = []) + fruits + [item, 1];
}else{
integer cnt = llList2Integer(fruits,idx) + 1;
fruits = llListReplaceList(fruits, [cnt], idx, idx);
}
}

integer function getCount(string item){
integer idx = llListFindList[fruits,[item]) + 1;
if(idx > 0){
return llList2Integer(fruits,idx);
}
return -1;
}

To add an "apple" you could then simply call add("apple";);

And, to get your item count, you simply call getCount("apple";);

An impl such as the above, trumps unnecessary resource intensive looping and reduces memory reqs. In other words, you've just reduced your list memory from 42 bytes to 13 bytes. And, if you add more apples and oranges, you're still only looking at 13 bytes. If you add a "banana" or whatever, the list memory will increase by the number of characters pls, one byte, at the very least.
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
12-15-2009 21:01
if you are building the list yourself (programatically) you can though. this is what Anna's suggestion looks like in a non strided version.

CODE

list gLstItems;
list gLstCount;

//-- when you recevie a new item to add
integer vIdxLst = llListFindList( gLstItems, (list)vStrAdd );
if (~vIdxLst){
gLstCount = llListReplaceList( gLstCount, llList2Integer( gLstCount, vIdxLst ) + 1, vIdxLst, vIdxLst );
else{
gLstItems += (list)vStrAdd;
gLstCount += (list)1;
}


then all you have to do to get a count of each unique item is check the same index in the count list. not using strides makes it easier to search a specific item, but using strides will allow you to sort on the count. but you can get the greatest and least counts by using llListStatistics to get the min or max in the count list, and then search for them to get the index (although this will only return the first one for items with the same count)

if the list is coming for an outside source that isn't read in one at a time, thihs should work to reduce the list to unique items, and counts.

CODE

integer vIntCnt;
list vLstTmp;
list vLstCount;
while ((vLstInput != vLstCount){
vLstTmp = llList2List( vLstInput, vIntCnt ) + llParseString2List ( llDumpList2String( vLstInput, ";" ), llList2List( vLstInput, vIntCnt ) + (list)";", [] );
vLstCount = (list)((vLstInput == vLstTmp) + 1);
vLstInput = vLstTmp;
++vIntCnt;
}
_____________________
|
| . "Cat-Like Typing Detected"
| . This post may contain errors in logic, spelling, and
| . grammar known to the SL populace to cause confusion
|
| - Please Use PHP tags when posting scripts/code, Thanks.
| - Can't See PHP or URL Tags Correctly? Check Out This Link...
| -
Nyx Alsop
Registered User
Join date: 14 Dec 2008
Posts: 252
12-16-2009 04:25
So basicly like

New item comes....find in list, if found update it's count, if not found add it to the list?
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
12-16-2009 09:03
From: Nyx Alsop
So basicly like

New item comes....find in list, if found update it's count, if not found add it to the list?

ayup
_____________________
|
| . "Cat-Like Typing Detected"
| . This post may contain errors in logic, spelling, and
| . grammar known to the SL populace to cause confusion
|
| - Please Use PHP tags when posting scripts/code, Thanks.
| - Can't See PHP or URL Tags Correctly? Check Out This Link...
| -