crazycodr/data-collection

Used to organise data in strict collection units

3.1.1 2014-02-24 15:43 UTC

README

This package contains facilities to easily specify strict type collections or lists such as the one you can find in other programming languages. (For example C# Generic Dictionnary/List);

Table of contents

  1. Installation
  2. Advantages and disadvantages
  3. Creating a data collection
  4. Creating your own KeyValuePairFilter
  5. Using the data collection

Installation

To install it, just include this requirement into your composer.json

{
    "require": {
        "crazycodr/data-collection": "3.*"
    }
}

And then run composer install/update as necessary.

Components of this package

There are two components provided with this package:

  1. Data\StrictList: A strict list that accepts normal array keys (Scalar values) by default but restricts the value as you see fit using a ValueFilter
  2. Data\StrictCollection: A strict collection that accepts any kind of key and value as you see fit using a KeyValuePairFilter

Advantages and disadvantages

There are many reasons why you would use the data-collection but there are also drawbacks and they are :

Advantages

  1. Data-Collection supports any type of key or value, traditionnal array supports only scalar keys
  2. Data-Collection/List enforces type safety for your collection/list, traditionnal array doesn't
  3. Data-Collection/List enforces it's rules by throwing exceptions instead of raising errors

Disadvantages

  1. Data-Collection/List uses a dual array storage mechanism with synched indexes, you can't get all the data with keys and values mixed together like a normal array
  2. Data-Collection doesn't implement ArrayObject thus you cannot use any standard array functions such as sorting, unique, etc. A workaround is to use other libraries that sort using an iterator such as Data-Sorter
  3. Data-Collection is slower than a normal array as it runs in the normal userspace and does a little more than just store data in a natural array fashion

Creating a data collection or data list

Creating a data collection/list is as simple as instanciating it and passing a type filter:

use \CrazyCodr\Data\StrictCollection;
use \CrazyCodr\Data\KeyValuePairFilters\ScalarObjectPairFilter;

$objectCollection = new StrictCollection(new ScalarObjectPairFilter());
use \CrazyCodr\Data\StrictList;
use \CrazyCodr\Data\ValueFilters\ObjectFilter;

$objectList = new StrictList(new ObjectFilter());

By default, data-collection comes with a few bundled KeyValuePair filters. The default ones provided with the initial version 3.0.0 are:

  1. ObjectObjectPairFilter
  2. ScalarObjectPairFilter
  3. ScalarScalarPairFilter

The data-list on it's side only features two default filters:

  1. ObjectFilter
  2. ScalarFilter

Important notes about keys

  1. Scalar Key filters allow only strings and integers just like the traditionnal array. It wouldn't make sense to use True/False as keys anyway. This is not applicable to the StrictList as it will type juggle the value just like a normal array!
  2. Square brackets in PHP automatically juggle keys, this is not a mechanism implemented by data-collection. Strings that are numeric are automatically converted into an integer and used as indexes normally speaking. Any fractional is automatically converted into a string and used as a key...

Creating your own KeyValuePairFilter or ValueFilter

It is recommended and very easy to create your own key value pair filter/value filter that you'll use within your project. Just create a class that implements \CrazyCodr\Data\KeyValuePairFilterInterface or \CrazyCodr\Data\ValueFilterInterface.

The \CrazyCodr\Data\KeyValuePairFilterInterface is comprised of two simple methods:

  • validateKey($key)
  • validateValue($value)

While the \CrazyCodr\Data\ValueFilterInterface contains only the value verification method:

  • validateValue($value)

They should return true if the key/value is valid and false if not.

Using the data collection/list

The data collection/list implements ArrayAccess, IteratorAggregate and Countable which is often more than enough for the use cases it has been designed for:

  1. Store type safe data into it
  2. Iterate it
  3. Retrieve/Alter data stored in it

Setting data into the collection/list

Using square brackets [] to set a value just like in a normal array allows you create key value pairs in the collection. In the case of the StrictCollection, note that you cannot use the NULL keys as it is of the NULL type and is usually reserved to create sequenced indexes. Using Null in a StrictCollection will result in an exception as it is not supported. For the StrictLists, the keys are supported but just like a normal array and an automatic type juggling is done for you:

  1. All boolean values are converted to ints (1 or 0)
  2. All numeric strings that are integers are converted to integers
  3. All negative integers are converted to strings
  4. Any scalar but not integral values left are converted to strings
$employeeCollection[$empSupervisor] = $emp;
$employeeCollection[$emp2->id] = $emp2;
$employeeCollection[] = $emp3; //Invalid
$employeeList[$empSupervisor] = $emp; //Invalid
$employeeList[$emp2->id] = $emp2;
$employeeList[] = $emp3;

Unsetting data from the collection/list

By calling unset() on the collection/list and passing it an existing key, you will delete the matching key and value pair from the collection:

//Unsetting data from the collection
unset($employeeCollection[$emp->id]);
unset($employeeList[$emp->id]);

Checking if a key is set

There are two ways to check if a key is set in the collection, the more traditionnal way would be to use array_key_exists() but since this is not an array, use isset(). Isset() will not throw false if the value is null but the key exists like in normal arrays, it will check for the key's existance and return true/false.

Another method (only for the collection) is to use findKey() which searches the collection of keys for the specified key. If found, it returns the index of the key or false if nothing found. Becareful, false and 0 are automatically juggled, use the strict comparison operator in this case (===):

if(isset($employeeCollection[$emp2->id]))
{
	//Exists
}
if(isset($employeeList[$emp2->id]))
{
	//Exists
}
if($employeeCollection->findKey($emp2->id) !== false)
{
	//Exists
}

Getting a value by key

To get a value associated with a key, just use the normal square brackets to access a key's content:

var_dump($employeeCollection[0]);
var_dump($employeeList[0]);

Getting all the keys or values in the collection

Getting all the keys or values stored in the collection is as easy as calling getKeys() or getValues(). Note that the data is returned as an indexed array. Indexes in keys correspond to the indexes in Values.

var_dump($employeeCollection->getKeys());
var_dump($employeeCollection->getValues());
var_dump($employeeList->getKeys());
var_dump($employeeList->getValues());