An xDict object is a collection based on array format which act as an array but with some subtlety and which can be used to build any other type of
collection easily such as queue,{max/min}heap,priority{collection},set,pair etc as you may see in the demonstrations files...
It also natively implements all the PHP functions which can be used on array to make the usage of an xDict object as pleasant
and extensive as PHP array.
Nb:for a true documentation see the file doc.txt.You can also get a partial documentation with the method xDict::help() for
all methods or the purpose of a specific method with xdict::help($methodname);
Strengths
*Supports array syntax (square brackets).
*supports(implements as methods) every array functions except array_fill and array_fill_keys we use instead fill_with and in_xdict instead of in_array
*supports modification of depth or first level inner elements:
objects implementing the arrayAccess interface do not allow this:
$object["anoffset"]["here"]=true;
$object["anoffset"][]=true;
unset($object["anoffset"]["here"]);
xDict thus allow that, this way
$object->SetInnerVal('["anoffset"]["here"]',true);
$object->SetInnerVal('["anoffset"][]',true);
$object->unsetInnerVal('["anoffset"]["here"]');
and you can use it on the first level or on any deep level even if it is an object entry eg:
$object->SetInnerVal("[0][1][0]['suffix']['verydeep'][1][3][4]",range(0,7));
$object->SetInnerVal("[0][1][0]['suffix']['verydeep'][1][3][4][]",range(0,7));
$object->unsetInnerVal("[0][1][0]['suffix']['verydeep'][1][3][4]"); provided that the row and the offset exists.
NB: SetInnerVal can be used to change an existing value,or to set a new one no matter the level and the complexity of the architecture
of the
xDict object exactly as we can do for PHP array.
*supports count() function
*debug info with var_dump show something like :
object(xDict)#1 (10) {
[-100]=>
int(0)
[-99]=>
int(6)
[-98]=>
int(12)
[-97]=>
int(18)
[-96]=>
int(24)
[-95]=>
int(30)
[-94]=>
int(36)
[-93]=>
int(42)
[-92]=>
int(48)
[-91]=>
int(54)
}
*supports fixed first offset integer value and fixed prefixed offsets values,fixed number of elements,
and all types as offset in non strict mode.
*very simple construction:
$obj=xdict(); //create an object with offset starting at 1
$obj=xdict(-1)//offset starting at -1;
$obj=xdict(0,'_')//offset starting at 0 and all offsets will be prefixed with _;
** you can also use the "new " keyword eg: $obj=new xDict(0,'_');.
*but there is also the strict mode which is on by default; you can turn it to off by specifying false:
$obj=xdict(0,'_',true);
In this mode(strict) all indices will always match the same pattern as the first index otherwise they can't be add ;
eg:
$obj=xdict(0,'_',true);
$obj[]=0;// now we have: object(xDict)#1 (1) {[_0]=>0}
$obj[]=1; // now we have: object(xDict)#1 (2) {[_0]=>0,[_1]=>1}
$obj[_10]=10;// now we have: object(xDict)#1 (3) {[_0]=>0,[_1]=>1,[_10]=>10}
$obj[]=11;// now we have: object(xDict)#1 (4) {[_0]=>0,[_1]=>1,[_10]=>10,[_11]=>11}
$obj[12]=12; //will do nothing in strict mode now we have:object(xDict)#1 (4) {[_0]=>0,[_1]=>1,[_10]=>10,[_11]=>11}
eg2:
$obj=xdict(0,'_',false);
$obj[]=0;// now we have: object(xDict)#1 (1) {[_0]=>0}
$obj[]=1; // now we have: object(xDict)#1 (2) {[_0]=>0,[_1]=>1}
$obj[_10]=10;// now we have: object(xDict)#1 (3) {[_0]=>0,[_1]=>1,[_10]=>10}
$obj[]=11;// now we have: object(xDict)#1 (4) {[_0]=>0,[_1]=>1,[_10]=>10,[_11]=>11}
$obj[12]=12; // now we have:object(xDict)#1 (5) {[_0]=>0,[_1]=>1,[_10]=>10,[_11]=>11,[12]=>12}
$obj[]=12;// now we have:object(xDict)#1 (6) {[_0]=>0,[_1]=>1,[_10]=>10,[_11]=>11,[12]=>12,[_12]=>12}
**you can even use any type as offset in this mode(non strict):
eg:
$obj[[1,2,3]]=1;
echo $obj[[1,2,3]] ; //will print 1
$x=new xdict();
$obj[$x]=1;
echo $obj[$x];//will print 1;
$x=fopen(__FILE__,'rb+');
$obj[$x]=1;
echo $obj[$x];//will print 1;
$obj[0.5]=1;
echo $obj[0.5] ; //will print 1
Nb: internally each invalid offset is stored as a hash (string format) for non float and as as simple string for float;
*and also type to return (array or xdict object)
eg:
$obj->chunk(2); will return an xdict object unless you specify it once while constructing the object for the first time
$x=xdict(0,'_',true/*or false*/,true/*means return array instead of xdict object*/);
now $obj->chunk(2) will return array instead of xdict object
nb: this is valid for all methods which can return array .
*and finally you can limit the number of entries:
eg:
$x=xdict(0,'_'/*can be empty string*/,true/*or false*/,true/*or false*/,10 /*will limit number of entry to 10,by default it is unlimited*/);
for ($i=0;$i<15;$i++){
$x[]=$i*3;
}
var_dump($x);
/*will print:
object(xDict)#13 (10) {
["_0"]=>
int(0)
["_1"]=>
int(3)
["_2"]=>
int(6)
["_3"]=>
int(9)
["_4"]=>
int(12)
["_5"]=>
int(15)
["_6"]=>
int(18)
["_7"]=>
int(21)
["_8"]=>
int(24)
["_9"]=>
int(27)
}
*/
as you may remark beyond the 10th entry there is no more insertion
*supports usage in string contest:
eg: echo $obj //will print something like{"-100":0,"-99":6,"-98":12,"-97":18,"-96":24,"-95":30,"-94":36,"-93":42,"-92":48,"-91":54}
*Supports Jsonencode function
eg:
echo json_encode($obj,JSON_PRETTY_PRINT);//will print something like;
{
"-100": 0,
"-99": 6,
"-98": 12,
"-97": 18,
"-96": 24,
"-95": 30,
"-94": 36,
"-93": 42,
"-92": 48,
"-91": 54
}
*is iterable: you can use foreach on it
*is callable :
when you use the syntax $obj(...$arguments) the value of each argument will be add to the xdict object following some rules
if the argument is an array or a xDict object each value in the argument will be add else each single argument will be add
so if you want to add an xDict object to another xDict object you may use the push method or the syntax $obj[]=$xdictobjecthere
eg:
$obj(5,4,3,function($v){return $v}) will add respectively 5,4,3,object(closure)#0{} but
$obj($array) and $obj($xdict) will add each value of the array/xdictobj trying to preserve the good keys as stated above;
*Supports extraction to first level global variables available anywhere in the script:
this works only if the fixed first offset is greater than 0 and if the strict mode is activated;
Except these conditions all the flags that you can use with the PHP native extract function can be used to extract the data
eg:
$obj=xdict(0,'_',true);
$obj->fill_with([2,5,6,7]);// now we have: object(xDict)#1 (4) {[_0]=>2,[_1]=>5,[_2]=>6,[_3]=>7}
$obj->extract(EXTR_PREFIX_SAME,'myxdict');
/*** now we have: $myxdict__0===2 $myxdict__1===5 $myxdict__2===6 $myxdict__3===7 available anywhere in the script. ***/
For more information about the flag constants ,read the extract function details in the PHP doc.
*Also simulate compact function and List structure implemented as restrictive native method
*Finally you can clear the xDict object content using $obj->clear() :
eg:
$obj=xdict(0,'_');
$obj->fill_with([2,5,6,7]);// now we have: object(xDict)#1 (4) {[_0]=>2,[_1]=>5,[_2]=>6,[_3]=>7}
$obj->clear() ;// now we have: object(xDict)#1 (0) {}
$obj[]=5 ;// now we have: object(xDict)#1 (1) {[_0]=>5}
*or create a shallow copy of an xDict object using $obj->copy():
eg:
$obj=xdict(0,'_');
$obj->fill_with([2,5,6,7]);// now we have: object(xDict)#1 (4) {[_0]=>2,[_1]=>5,[_2]=>6,[_3]=>7}
$obj2=$obj->copy() ;// now we have: object(xDict)#2 (4) {[_0]=>2,[_1]=>5,[_2]=>6,[_3]=>7}
$obj2[]=5 ;// now we have: object(xDict)#2 (5) {[_0]=>2,[_1]=>5,[_2]=>6,[_3]=>7,[_4]=>5}
*Nb: some of the methods differ slightly from the existing array methods :
eg: slice and splice :the array to slice or splice always start from the specified offset even if the the offset is negative;
read the doc.txt to know more about all the major differences with native PHP functions
*Nb1: you must not test an xDict obj with the empty function except if it is for the variable existence you can use
instead to know if it is empty the method isEmpty just as $obj->isEmpty();
*Nb2:some of you like the following snippet : list($var,$anothvar)=each($array) you can use list($var1,$anothvar)=$obj->each()
*Nb3: the count_values method doesn't act like array_count_values for it count every values even boolean ,objects and arrays
*Nb4: the xdict class natively implements the methods of the innovative array_depth package as : depth,homogeneous,rowsandcol,signature
and typesof you can go to this package page to understand their importance.
*Nb5: you can flip with the method flip() an xDict object whatever the types it contains.No errors will be shown as
the invalid offset types will be replaced by their hashes or their string value.
*Nb6: Every methods which accept array as parameter also accept any iterable object as parameter.
*NB7:
keep in mind that the xDict class is really useful but can't replace an array in all contests because it is really slow in some
contests specially when a sorting occurs.This is because the class always take the time to prepare the array before run the
method on it .This way you will never get errors nor be stressed about the real types used in the array in order to choose
the most efficient algorithm.This works specially well when array or object (that doesn't implement
the method __toString ) to string conversion must occurs .The class simply skip the invalid data in some case or serialized them
to allow String comparison.This is the real reason for its slowness in some cases and one may found this as a real handicap(only for very large array).
AS most of the methods are similar to the array functions and implicitly use them you can refer to these functions to
understand the usage of each method but:
For more informations see the examples files:
you can see some very easy and functional implementations of common data structures such as Queue ,Priority Queue,Stack,Pair using only xDict object.
And also many other how to use examples in the examples directory.
You can also take a look at the list of methods sorted alphabetically and their purpose in the file doc.txt
You can use the forum for bug reporting and other.And don't forget to rate the package.
|