Difference between revisions of "Talk:Array"

From Second Life Wiki
Jump to navigation Jump to search
Line 496: Line 496:
:That is going to be a very slow implementation. You would be better off using [[llListFindList]]. -- [[User:Strife Onizuka|Strife Onizuka]] 13:55, 12 November 2007 (PST)
:That is going to be a very slow implementation. You would be better off using [[llListFindList]]. -- [[User:Strife Onizuka|Strife Onizuka]] 13:55, 12 November 2007 (PST)
::[[llListFindList]] may provide a faster method to locate a given value within a list, however implementing an associative array using llListFindList would yield a crippled associative array.  From the docs: "Returns an integer that is the index of the first instance of test in src." Thus, for a given array [ k1 => v1, k2 => v2, k3 => v3 ] you would not be able to have more than one vx with the same value, or a vx with the same value as a kx.  You couldn't use this simple data set [ 3 => 1, 2 => 1, 1 => 1 ] without adding special cases or a more complex storage structure, which may cancel any benefit gained by using llListFindList. --[[User:Asha Vultee|Asha Vultee]] 10:59, 19 November 2007 (PST)
::[[llListFindList]] may provide a faster method to locate a given value within a list, however implementing an associative array using llListFindList would yield a crippled associative array.  From the docs: "Returns an integer that is the index of the first instance of test in src." Thus, for a given array [ k1 => v1, k2 => v2, k3 => v3 ] you would not be able to have more than one vx with the same value, or a vx with the same value as a kx.  You couldn't use this simple data set [ 3 => 1, 2 => 1, 1 => 1 ] without adding special cases or a more complex storage structure, which may cancel any benefit gained by using llListFindList. --[[User:Asha Vultee|Asha Vultee]] 10:59, 19 November 2007 (PST)
:::You use a buffer and trim the found entries off the buffer as you parse it. Take a look at [[https://wiki.secondlife.com/wiki/Library_Combined_Library#Replace|str_replace]] for an example of this sort of logic in action. -- [[User:Strife Onizuka|Strife Onizuka]] 13:42, 19 November 2007 (PST)

Revision as of 13:42, 19 November 2007

Here is an elementary implementation of an associative array using the list datatype as a primitive storage mechanism.

////////////////////////////////////////////////////////////////////////////////////////////
// Asha's Associative Array
//
// ______Release 0.1______
// Basic functionality.
// Copy this code to your script
// and use the av_* functions to access
//
// TO SAVE DATA:
// av_store_assoc( [ key, value ] );
//
// TO REPLACE DATA: (currently, this is a synonum for av_store_assoc)
// av_replace_assoc( [ key, value ] );
//
// TO REMOVE DATA:
// av_remove_assoc( [ key, UNUSED ] );
//
// TO RETRIEVE DATA:
// av_assoc_get_by_key( [ key, UNUSED ] );
// av_assoc_get_by_val( [ UNUSED, val ] );
//
// CAUTION: av_assoc_get_by_val() may return a list of more than 2 elements, where the list is
// defined as [ key1, val1, key2, val2 ... keyn, valn ]
//
// TO WHACK THE LIST:
// av_reset_assoc( string reserved );
//
// CAUTION: in order to maintain API compatability with future releases, use
//  av_* functions instead of calling any LSL list functions or operators directly.
////////////////////////////////////////////////////////////////////////////////////////////
// START COPYING HERE
list av_assoc_list_storage;
integer av_assoc_list_width = 3;
integer av_index_offset = 0;
integer av_assoc_key_offset = 1;
integer av_assoc_val_offset = 2;
integer av_assoc_list_id = 0;

av_reset_assoc( string rsvd )
{
    av_assoc_list_storage = [];
}

av_store_assoc( list nvpair )
{
    integer i;
    integer j;
    integer matched;

    float _currkey_float;
    float _currval_float;
    integer _currkey_integer;
    integer _currval_integer;
    string _currkey_string;
    string _currval_string;
    key _currkey_key;
    key _currval_key;
    vector _currkey_vector;
    vector _currval_vector;
    rotation _currkey_rotation;
    rotation _currval_rotation;
    
    integer key_type;
    integer inkey_type;
    
    inkey_type = llGetListEntryType( nvpair, 0 );
    matched = 0;
    
    j = llGetListLength( av_assoc_list_storage );
    
    if ( 0 == j )
    {
        av_assoc_list_storage += (av_assoc_list_id++);
        av_assoc_list_storage += nvpair;
        return;
    }
    
    for ( i = 0; i < j; i+= av_assoc_list_width )
    {
        key_type = llGetListEntryType( av_assoc_list_storage, i+av_assoc_key_offset );
        if ( key_type == inkey_type )
        {
            if ( key_type == TYPE_INTEGER )
            {
                _currkey_integer = llList2Integer( av_assoc_list_storage, i+av_assoc_key_offset );
                _currval_integer = llList2Integer( nvpair, 0 );
                if ( _currkey_integer == _currval_integer )
                {
                    matched = 1;
                }
            }
            else if ( key_type == TYPE_STRING )
            {
                _currkey_string = llList2String( av_assoc_list_storage, i+av_assoc_key_offset );
                _currval_string = llList2String( nvpair, 0 );
                if ( _currkey_string == _currval_string )
                {
                    matched = 1;
                }
            }
            else if ( key_type == TYPE_VECTOR )
            {
                _currkey_vector = llList2Vector( av_assoc_list_storage, i+av_assoc_key_offset );
                _currval_vector = llList2Vector( nvpair, 0 );
                if ( _currkey_vector == _currval_vector )
                {
                    matched = 1;
                }
            }
            else if ( key_type == TYPE_ROTATION )
            {
                _currkey_rotation = llList2Rot( av_assoc_list_storage, i+av_assoc_key_offset );
                _currval_rotation = llList2Rot( nvpair, 0 );
                if ( _currkey_rotation == _currval_rotation )
                {
                    matched = 1;
                }
            }
            else if ( key_type == TYPE_FLOAT )
            {
                _currkey_float = llList2Float( av_assoc_list_storage, i+av_assoc_key_offset );
                _currval_float = llList2Float( nvpair, 0 );
                if ( _currkey_rotation == _currval_rotation )
                {
                    matched = 1;
                }
            }
            else if ( key_type == TYPE_KEY )
            {
                _currkey_key = llList2Key( av_assoc_list_storage, i+av_assoc_key_offset );
                _currval_key = llList2Key( nvpair, 0 );
                if ( _currkey_key == _currval_key )
                {
                    matched = 1;
                }
            }
            
            if ( matched )
            {
                av_assoc_list_storage = llListReplaceList( av_assoc_list_storage, nvpair, i+1, i+2 );
                return;
            }
        }
    }

    av_assoc_list_storage += (av_assoc_list_id++);
    av_assoc_list_storage = av_assoc_list_storage + nvpair;
}

av_replace_assoc( list nvpair )
{
    av_store_assoc( nvpair );
}

av_remove_assoc( list nvpair )
{
    integer i;
    integer j;
    integer matched;
    float _currkey_float;
    float _currval_float;
    integer _currkey_integer;
    integer _currval_integer;
    string _currkey_string;
    string _currval_string;
    key _currkey_key;
    key _currval_key;
    vector _currkey_vector;
    vector _currval_vector;
    rotation _currkey_rotation;
    rotation _currval_rotation;
    
    integer key_type;
    integer inkey_type;
    
    inkey_type = llGetListEntryType( nvpair, 0 );
    matched = 0;
    
    j = llGetListLength( av_assoc_list_storage );
    
    if ( 0 == j )
    {
        return;
    }
    
    for ( i = 0; i < j; i+= av_assoc_list_width )
    {
        key_type = llGetListEntryType( av_assoc_list_storage, i+av_assoc_key_offset );
        if ( key_type == inkey_type )
        {
            if ( key_type == TYPE_INTEGER )
            {
                _currkey_integer = llList2Integer( av_assoc_list_storage, i+av_assoc_key_offset );
                _currval_integer = llList2Integer( nvpair, 0 );
                if ( _currkey_integer == _currval_integer )
                {
                    matched = 1;
                }
            }
            else if ( key_type == TYPE_STRING )
            {
                _currkey_string = llList2String( av_assoc_list_storage, i+av_assoc_key_offset );
                _currval_string = llList2String( nvpair, 0 );
                if ( _currkey_string == _currval_string )
                {
                    matched = 1;
                }
            }
            else if ( key_type == TYPE_VECTOR )
            {
                _currkey_vector = llList2Vector( av_assoc_list_storage, i+av_assoc_key_offset );
                _currval_vector = llList2Vector( nvpair, 0 );
                if ( _currkey_vector == _currval_vector )
                {
                    matched = 1;
                }
            }
            else if ( key_type == TYPE_ROTATION )
            {
                _currkey_rotation = llList2Rot( av_assoc_list_storage, i+av_assoc_key_offset );
                _currval_rotation = llList2Rot( nvpair, 0 );
                if ( _currkey_rotation == _currval_rotation )
                {
                    matched = 1;
                }
            }
            else if ( key_type == TYPE_FLOAT )
            {
                _currkey_float = llList2Float( av_assoc_list_storage, i+av_assoc_key_offset );
                _currval_float = llList2Float( nvpair, 0 );
                if ( _currkey_rotation == _currval_rotation )
                {
                    matched = 1;
                }
            }
            else if ( key_type == TYPE_KEY )
            {
                _currkey_key = llList2Key( av_assoc_list_storage, i+av_assoc_key_offset );
                _currval_key = llList2Key( nvpair, 0 );
                if ( _currkey_key == _currval_key )
                {
                    matched = 1;
                }
            }
            
            if ( matched )
            {
                av_assoc_list_storage = llDeleteSubList( av_assoc_list_storage, i, i+2 );
                return;
            }
        }
    }

}

list av_assoc_get_by_key( list nvpair )
{
    integer i;
    integer j;
    integer matched;
    float _currkey_float;
    float _currval_float;
    integer _currkey_integer;
    integer _currval_integer;
    string _currkey_string;
    string _currval_string;
    key _currkey_key;
    key _currval_key;
    vector _currkey_vector;
    vector _currval_vector;
    rotation _currkey_rotation;
    rotation _currval_rotation;
    
    integer key_type;
    integer inkey_type;
    
    inkey_type = llGetListEntryType( nvpair, 0 );
    matched = 0;
    
    j = llGetListLength( av_assoc_list_storage );
    
    if ( 0 == j )
    {
        return( [] );
    }
    
    for ( i = 0; i < j; i+= av_assoc_list_width )
    {
        key_type = llGetListEntryType( av_assoc_list_storage, i+av_assoc_key_offset );
        if ( key_type == inkey_type )
        {
            if ( key_type == TYPE_INTEGER )
            {
                _currkey_integer = llList2Integer( av_assoc_list_storage, i+av_assoc_key_offset );
                _currval_integer = llList2Integer( nvpair, 0 );
                if ( _currkey_integer == _currval_integer )
                {
                    matched = 1;
                }
            }
            else if ( key_type == TYPE_STRING )
            {
                _currkey_string = llList2String( av_assoc_list_storage, i+av_assoc_key_offset );
                _currval_string = llList2String( nvpair, 0 );
                if ( _currkey_string == _currval_string )
                {
                    matched = 1;
                }
            }
            else if ( key_type == TYPE_VECTOR )
            {
                _currkey_vector = llList2Vector( av_assoc_list_storage, i+av_assoc_key_offset );
                _currval_vector = llList2Vector( nvpair, 0 );
                if ( _currkey_vector == _currval_vector )
                {
                    matched = 1;
                }
            }
            else if ( key_type == TYPE_ROTATION )
            {
                _currkey_rotation = llList2Rot( av_assoc_list_storage, i+av_assoc_key_offset );
                _currval_rotation = llList2Rot( nvpair, 0 );
                if ( _currkey_rotation == _currval_rotation )
                {
                    matched = 1;
                }
            }
            else if ( key_type == TYPE_FLOAT )
            {
                _currkey_float = llList2Float( av_assoc_list_storage, i+av_assoc_key_offset );
                _currval_float = llList2Float( nvpair, 0 );
                if ( _currkey_rotation == _currval_rotation )
                {
                    matched = 1;
                }
            }
            else if ( key_type == TYPE_KEY )
            {
                _currkey_key = llList2Key( av_assoc_list_storage, i+av_assoc_key_offset );
                _currval_key = llList2Key( nvpair, 0 );
                if ( _currkey_key == _currval_key )
                {
                    matched = 1;
                }
            }
            
            if ( matched )
            {
                list l = llList2List( av_assoc_list_storage, i+1, i+2 );
                return( l );
            }
        }
    }
    return( [] );
}

list av_assoc_get_by_val( list nvpair )
{
    integer i;
    integer j;
    integer matched;
    list ret;
    float _currkey_float;
    float _currval_float;
    integer _currkey_integer;
    integer _currval_integer;
    string _currkey_string;
    string _currval_string;
    key _currkey_key;
    key _currval_key;
    vector _currkey_vector;
    vector _currval_vector;
    rotation _currkey_rotation;
    rotation _currval_rotation;
    
    integer key_type;
    integer inkey_type;
    
    inkey_type = llGetListEntryType( nvpair, 1 );
    matched = 0;
    
    j = llGetListLength( av_assoc_list_storage );
    
    if ( 0 == j )
    {
        return( [] );
    }
    
    for ( i = 0; i < j; i+= av_assoc_list_width )
    {
        key_type = llGetListEntryType( av_assoc_list_storage, i+av_assoc_val_offset );
        if ( key_type == inkey_type )
        {
            if ( key_type == TYPE_INTEGER )
            {
                _currkey_integer = llList2Integer( av_assoc_list_storage, i+av_assoc_val_offset );
                _currval_integer = llList2Integer( nvpair, 1 );
                if ( _currkey_integer == _currval_integer )
                {
                    matched = 1;
                }
            }
            else if ( key_type == TYPE_STRING )
            {
                _currkey_string = llList2String( av_assoc_list_storage, i+av_assoc_val_offset );
                _currval_string = llList2String( nvpair, 1 );
                if ( _currkey_string == _currval_string )
                {
                    matched = 1;
                }
            }
            else if ( key_type == TYPE_VECTOR )
            {
                _currkey_vector = llList2Vector( av_assoc_list_storage, i+av_assoc_val_offset );
                _currval_vector = llList2Vector( nvpair, 1 );
                if ( _currkey_vector == _currval_vector )
                {
                    matched = 1;
                }
            }
            else if ( key_type == TYPE_ROTATION )
            {
                _currkey_rotation = llList2Rot( av_assoc_list_storage, i+av_assoc_val_offset );
                _currval_rotation = llList2Rot( nvpair, 1 );
                if ( _currkey_rotation == _currval_rotation )
                {
                    matched = 1;
                }
            }
            else if ( key_type == TYPE_FLOAT )
            {
                _currkey_float = llList2Float( av_assoc_list_storage, i+av_assoc_val_offset );
                _currval_float = llList2Float( nvpair, 1 );
                if ( _currkey_rotation == _currval_rotation )
                {
                    matched = 1;
                }
            }
            else if ( key_type == TYPE_KEY )
            {
                _currkey_key = llList2Key( av_assoc_list_storage, i+av_assoc_val_offset );
                _currval_key = llList2Key( nvpair, 1 );
                if ( _currkey_key == _currval_key )
                {
                    matched = 1;
                }
            }
            
            if ( matched )
            {
                ret += llList2List( av_assoc_list_storage, i+1, i+2 );
            }
        }
    }
    return( ret );

}

// STOP COPYING HERE
////////////////////////////////////////////////////////////////////////////////////////////

default
{
    state_entry()
    {
        llOwnerSay( "Asha's Associative Array Test Ready" );
    }

    touch_start(integer total_number)
    {
    
        list l = [ 123, "Hello" ];
        list m = [ 456, "Wassup" ];
        list n = [ 789, "Yadda Yadda" ];
        list o = [ 790, "Yadda Yadda" ];
        list p = [ 791, "yadda YADDA" ];
        
        av_store_assoc( l );
        av_store_assoc( m );
        av_store_assoc( l );
        av_remove_assoc( l );
        
        l = av_assoc_get_by_key( m );
        llOwnerSay( llList2CSV( l ) );
        
        av_store_assoc( n );
        av_store_assoc( o );
        av_store_assoc( p );
        llOwnerSay( llList2CSV( av_assoc_get_by_val( [ "", "Yadda Yadda" ] ) ) );
    }
}

--Asha Vultee 12:11, 12 November 2007 (PST)

That is going to be a very slow implementation. You would be better off using llListFindList. -- Strife Onizuka 13:55, 12 November 2007 (PST)
llListFindList may provide a faster method to locate a given value within a list, however implementing an associative array using llListFindList would yield a crippled associative array. From the docs: "Returns an integer that is the index of the first instance of test in src." Thus, for a given array [ k1 => v1, k2 => v2, k3 => v3 ] you would not be able to have more than one vx with the same value, or a vx with the same value as a kx. You couldn't use this simple data set [ 3 => 1, 2 => 1, 1 => 1 ] without adding special cases or a more complex storage structure, which may cancel any benefit gained by using llListFindList. --Asha Vultee 10:59, 19 November 2007 (PST)
You use a buffer and trim the found entries off the buffer as you parse it. Take a look at [[1]] for an example of this sort of logic in action. -- Strife Onizuka 13:42, 19 November 2007 (PST)