/// @addtogroup sefun
/// @{
/// @file arrays
/// @brief simul_efuns for array manipulations
/// based on deadsouls
/// @author Gwenhwyvar
/// @version 0.1.0
/// @date 2016-01-24

// --------------------------------------------------------------------------
/// @brief scramble_array 
/// @Param arr
/// @Returns copy of arr in random order
// --------------------------------------------------------------------------
public mixed *scramble_array(mixed *arr)
{
    return sort_array(copy(arr), (: random(3) - 1 :) );
}
// --------------------------------------------------------------------------
/// @brief distinct_array 
/// @Param arr
/// @Returns - copy of arr with duplicates removed
// --------------------------------------------------------------------------
public mixed *distinct_array(mixed *arr)
{
    int     i   = sizeof(arr) - 1;
    mapping tmp = allocate_mapping(i + 1);

    for(; i >= 0;)
        tmp[arr[i--]] = 1;
    return keys(tmp);
}
// --------------------------------------------------------------------------
/// @brief unique_mapping 
/// same semantic as unique_array but retains the return values of the
/// seperator function as keys into the returned mapping
/// @Param arr
/// @Param sep
/// @Param skip
/// @Returns 
// --------------------------------------------------------------------------
public varargs mapping unique_mapping(mixed *arr, mixed sep, mixed skip)
{
    mapping ret;
    int     st;

    if(!arr || !pointerp(arr))
        return ([]);

    if(stringp(sep))
    {
        ret = ([]);
        st = nullp(skip);
        foreach(mixed elem in arr)
        {
            mixed val;

            // sep is string => only objects allowed
            if(!objectp(elem))
                continue;
            val = (mixed)call_other(elem, sep);
            if(!st && (val == skip))
                continue;
            if(!ret[val])
                ret[val] = ({ elem });
            else
                ret[val] += ({ elem });
        }
    }
    else if(functionp(sep))
    {
        ret = ([]);
        st = nullp(skip);
        foreach(mixed elem in arr)
        {
            mixed val;

            val = evalute(sep, elem);
            if(!st && (val == skip))
                continue;
            if(!ret[val])
                ret[val] = ({ elem });
            else
                ret[val] += ({ elem });
        }
    }
    else
        error(TYPE_ERROR("sefun::unique_mapping", "2", typeof(sep), "string|function"));
}
///  @}
