From e2ac0b285e8051068888d8059919aba748cf8c2c Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Sat, 29 Nov 2014 04:06:28 +0300 Subject: [PATCH] Guide chapter about ArrayHelper --- docs/guide/README.md | 2 +- docs/guide/helper-array.md | 311 ++++++++++++++++++++++++++++++++++ docs/guide/helper-overview.md | 2 +- 3 files changed, 313 insertions(+), 2 deletions(-) create mode 100644 docs/guide/helper-array.md diff --git a/docs/guide/README.md b/docs/guide/README.md index 3c0c2dc6fa..64afc143c4 100644 --- a/docs/guide/README.md +++ b/docs/guide/README.md @@ -192,7 +192,7 @@ Helpers ------- * [Overview](helper-overview.md) -* **TBD** [ArrayHelper](helper-array.md) +* [ArrayHelper](helper-array.md) * **TBD** [Html](helper-html.md) * **TBD** [Url](helper-url.md) * **TBD** [Security](helper-security.md) diff --git a/docs/guide/helper-array.md b/docs/guide/helper-array.md new file mode 100644 index 0000000000..b34e7a598c --- /dev/null +++ b/docs/guide/helper-array.md @@ -0,0 +1,311 @@ +ArrayHelper +=========== + +Additionally to [rich set of PHP array functions](http://php.net/manual/en/book.array.php) Yii array helper provides +extra static methods allowing you to deal with arrays more efficiently. + + +Getting values +-------------- + +### Getting a single value + +Retrieving values from an array, an object or a complex structure consisting of both using standard PHP is quite +repetitive. You have to check if key exists with `isset` first, then if it does you're getting it, if not, +providing default value: + +```php +class User +{ + public $name = 'Alex'; +} + +$array = [ + 'foo' => [ + 'bar' => new User(), + ] +]; + +$value = isset($array['foo']['bar']->name) ? $array['foo']['bar']->name : null; +``` + +Yii provides a very convenient method to do it: + +```php +$value = ArrayHelper::getValue($array, 'foo.bar.name'); +``` + +First method argument is where we're getting value from. Second argument specifies how to get the data. It could be one +of the following: + +- Name of array key or object property to retieve value from. +- Set of dot separated array key or object property names. The one we've used in the example above. +- A callback returning a value. + +The callback should be the following: + +```php +$fullName = ArrayHelper::getValue($user, function ($user, $defaultValue) { + return $user->firstName . ' ' . $user->lastName; +}); +``` + +Third optional argument is default value which is `null` if not specified. Could be used as follows: + +```php +$username = ArrayHelper::getValue($comment, 'user.username', 'Unknown'); +``` + +In case you want to get the value and then immediately remove it from array you can use `remove` method: + +```php +$array = ['type' => 'A', 'options' => [1, 2]]; +$type = ArrayHelper::remove($array, 'type'); +``` + +After executing the code `$array` will contain `['options' => [1, 2]]` and `$type` will be `A`. Note that unlike +`getValue` method, `remove` supports simple key names only. + + +### Checking if key exists + +`ArrayHelper::keyExists` works the same way as [array_key_exists](http://php.net/manual/en/function.array-key-exists.php) +except when trird argument is `false`. In this case it checks for a key in case insensitive manner: + +```php +$data1 = [ + 'userName' => 'Alex', +]; + +$data2 = [ + 'username' => 'Carsten', +]; + +if (!ArrayHelper::keyExists('username', $data1, false) || !ArrayHelper::keyExists('username', $data2, false)) { + echo "Please provide username."; +} +``` + +### Getting a column + +Often you need to get a column of values from array of data rows or objects. Common keys is getting a list of IDs. + +```php +$data = [ + ['id' => '123', 'data' => 'abc'], + ['id' => '345', 'data' => 'def'], +]; +$ids = ArrayHelper::getColumn($array, 'id'); +``` + +The result will be `['123', '345']`. + +If additional transformations are required or the way of getting value is complex, second argument could be specified +as an anonymous function: + +```php +$result = ArrayHelper::getColumn($array, function ($element) { + return $element['id']; +}); +``` + +Index array by key specified +---------------------------- + +In order to indexes an array according to a specified key `index` method could be used. The input array should be +multidimensional or an array of objects. The key can be a key name of the sub-array, a property name of object, or +an anonymous function which returns the key value given an array element. + +If a key value is null, the corresponding array element will be discarded and not put in the result. For example, + +```php +$array = [ + ['id' => '123', 'data' => 'abc'], + ['id' => '345', 'data' => 'def'], +]; +$result = ArrayHelper::index($array, 'id'); +// the result is: +// [ +// '123' => ['id' => '123', 'data' => 'abc'], +// '345' => ['id' => '345', 'data' => 'def'], +// ] + +// using anonymous function +$result = ArrayHelper::index($array, function ($element) { + return $element['id']; +}); +``` + + + +Map array +--------- + +In order to build a map (key-value pairs) from a multidimensional array or an array of objects you can use `map` method. +The `$from` and `$to` parameters specify the key names or property names to set up the map. Optionally, one can further +group the map according to a grouping field `$group`. For example, + +```php +$array = [ + ['id' => '123', 'name' => 'aaa', 'class' => 'x'], + ['id' => '124', 'name' => 'bbb', 'class' => 'x'], + ['id' => '345', 'name' => 'ccc', 'class' => 'y'], +); + +$result = ArrayHelper::map($array, 'id', 'name'); +// the result is: +// [ +// '123' => 'aaa', +// '124' => 'bbb', +// '345' => 'ccc', +// ] + +$result = ArrayHelper::map($array, 'id', 'name', 'class'); +// the result is: +// [ +// 'x' => [ +// '123' => 'aaa', +// '124' => 'bbb', +// ], +// 'y' => [ +// '345' => 'ccc', +// ], +// ] +``` + + +Sort array +---------- + +`sort` method helps to sort an array of objects or nested arrays by one or several keys. For example, + +```php +$data = [ + ['age' => 30, 'name' => 'Alexander'], + ['age' => 30, 'name' => 'Brian'], + ['age' => 19, 'name' => 'Barney'], +]; +ArrayHelper::multisort($data, ['age', 'name'], [ArrayHelper::SORT_ASC, ArrayHelper::SORT_DESC]); +``` + +After sorting we'll get the following in `$data`: + +```php +[ + ['age' => 19, 'name' => 'Barney'], + ['age' => 30, 'name' => 'Brian'], + ['age' => 30, 'name' => 'Alexander'], +]; +``` + +Second argument that specifies keys to sort by could be a string if it's a single key, an array in case of multiple keys +or an anonymous function like the following one: + +```php +ArrayHelper::multisort($data, function($item) { + return isset($item['age']) ? ['age', 'name'] : 'name'; +}); +``` + +Third argument is direction. In case of sorting by a single key it could be either `ArrayHelper::SORT_ASC` or +`ArrayHelper::SORT_DESC`. If sorting by multiple values you can sort each value differently by providing an array of +sort direction. + +Last argument is PHP sort flag that could take the same values as the ones passed to +PHP [sort()](http://php.net/manual/en/function.sort.php). + + +Finding out the type of array +----------------------------- + + +It is handy to know whether array is indexed or an associative. Here's an example: + +```php +// no keys specified +$indexed = ['Qiang', 'Paul']; +echo ArrayHelper::isIndexed($indexed); + +// all keys are strings +$associative = ['framework' => 'Yii', 'version' => '2.0']; +echo ArrayHelper::isAssociative($associative); +``` + + +HTML-encoding and HTML-decoding values +-------------------------------------- + +In order to encode or decode special characters in an array of strings into HTML entities you can use the following: + +```php +$encoded = ArrayHelper::htmlEncode($data); +$decoded = ArrayHelper::htmlDecode($data); +``` + +Only values will be encoded by default. By passing second argument as `false` you can encode arrays keys as well. +Encoding will use application charset and could be changed via third argument. + +Merging arrays +-------------- + + /** + * Merges two or more arrays into one recursively. + * If each array has an element with the same string key value, the latter + * will overwrite the former (different from array_merge_recursive). + * Recursive merging will be conducted if both arrays have an element of array + * type and are having the same key. + * For integer-keyed elements, the elements from the latter array will + * be appended to the former array. + * @param array $a array to be merged to + * @param array $b array to be merged from. You can specify additional + * arrays via third argument, fourth argument etc. + * @return array the merged array (the original arrays are not changed.) + */ + public static function merge($a, $b) + + +Getting array from object +------------------------- + +Often you need to convert an object or an array of objects into array. The most common case is converting active record +models in order to serve data arrays via REST API or use it otherwise. The following code could be used to do it: + +```php +$posts = Post::find()->limit(10)->all(); +$data = ArrayHelper::toArray($post, [ + 'app\models\Post' => [ + 'id', + 'title', + // the key name in array result => property name + 'createTime' => 'created_at', + // the key name in array result => anonymous function + 'length' => function ($post) { + return strlen($post->content); + }, + ], +]); +``` + +The first argument contains the data we want to convert. In our case we're converting a `Post` AR model. + +The second argument is conversion mapping per class. We're setting a mapping for `Post` model. +Each mapping array contains a set of mappings. Each mapping could be: + +- A field name to include as is. +- A key-value pair of desired array key name and model colum name to take value from. +- A key-value pair of desired array key name and a callback which return value will be used. + +The result of conversion above will be: + + +```php +[ + 'id' => 123, + 'title' => 'test', + 'createTime' => '2013-01-01 12:00AM', + 'length' => 301, +] +``` + +It is possible to provide default way of converting object to array for a specific class by implementing +[[yii\base\Arrayable|Arrayable]] interface in that class. \ No newline at end of file diff --git a/docs/guide/helper-overview.md b/docs/guide/helper-overview.md index 3764a156c3..cdc4e925b4 100644 --- a/docs/guide/helper-overview.md +++ b/docs/guide/helper-overview.md @@ -25,7 +25,7 @@ Core Helper Classes The following core helper classes are provided in the Yii releases: -- ArrayHelper +- [ArrayHelper](helper-array.md) - Console - FileHelper - Html