A library that extends PHP's native string functionality
This library is compatible with PHP version 7.2, 7.3, 7.4, 8.0, 8.1, 8.2, 8.3 and 8.4.
This library depends on
Installation is simple using composer.
composer require kusabi/collectionsOr simply add it to your composer.json file
{
"require": {
"kusabi/collections": "^1.0"
}
}This library follows PSR-1 & PSR-2 standards.
Before pushing any changes, please ensure the unit tests are all passing.
If possible, feel free to improve coverage in a separate commit.
vendor/bin/phpunitBefore pushing, please ensure you have run the code sniffer. Only run it using the lowest support PHP version (7.2)
vendor/bin/php-cs-fixer fixBefore pushing, please ensure you have run the static analyses tool.
vendor/bin/phanBefore pushing, please ensure you have checked the benchmarks and ensured that your code has not introduced any slowdowns.
Feel free to speed up existing code, in a separate commit.
Feel free to add more benchmarks for greater coverage, in a separate commit.
vendor/bin/phpbench run --report=speed
vendor/bin/phpbench run --report=speed --output=markdown
vendor/bin/phpbench run --report=speed --filter=benchNetFromTax --iterations=50 --revs=50000
vendor/bin/phpbench xdebug:profile
vendor/bin/phpbench xdebug:profile --guiThis library adds a new class that can wrap around native arrays to mke interactions with them quicker and simpler.
Below you can find links to the documentation for the new features.
use Kusabi\Collection\Collection;
// Using the constructor
$collection = new Collection();
$collection = new Collection([1, 2, 3]);
// Using the chainable constructor
$collection = Collection::instance();
$collection = Collection::instance([1, 2, 3]);
// Create using a range
$celsius = Collection::range(0, 100);
$alphabet = Collection::range('a', 'z');
$evens = Collection::range(0, 100, 2);use Kusabi\Collection\Collection;
// Collections can be used exactly like a normal array
$collection = new Collection([1, 2, 3]);
$collection[] = 4;
$collection['test'] = 5;
echo $collection[1]; // 2
// Getting the size of the collection
echo count($collection); // 5
echo $collection->count(); // 5
// Get the underlying array
$array = $collection->array();
array_change_key_case Changes the case of all keys in an array
use Kusabi\Collection\Collection;
$collection = new Collection(["FirSt" => 1, "SecOnd" => 4]);
$collection->changeKeyCase(CASE_UPPER); // ["FIRST" => 1, "SECOND" => 4]
$collection->changeKeyCase(CASE_LOWER); // ["first" => 1, "second" => 4]array_chunk Split an array into chunks
use Kusabi\Collection\Collection;
$collection = Collection::range(1, 100);
$chunks = $collection->chunk(10);array_column Return the values from a single column in the input array
use Kusabi\Collection\Collection;
$collection = new Collection([
'player_1' => [
'name' => 'John',
'hp' => 50,
'exp' => 1000
],
'player_2' => [
'name' => 'Jane',
'hp' => 70,
'exp' => 1000
]
]);
$hps = $collection->column('hp'); // [50, 70]
$hps = $collection->column('hp', 'name'); // ['John' => 50, 'Jane' => 70]array_combine Creates an array by using one array for keys and another for its values
use Kusabi\Collection\Collection;
$keys = new Collection(['a', 'b', 'c'])
$combinedWithArray = $keys->combine(['x', 'y', 'z']);
$combinedWithCollection = $keys->combine(new Collection(['x', 'y', 'z']));array_count_values Counts all the values of an array
use Kusabi\Collection\Collection;
$collection = new Collection([1, 2, 3, 1, 2, 4, 'a', 'a', 1]);
$appearances = $collection->countValues(); // [1 => 3, 2 => 2, 3 => 1, 4 => 1, 'a' => 2]array_diff_assoc Computes the difference of arrays with additional index check
use Kusabi\Collection\Collection;
Collection::instance([1, 2, 3, 4, 5, 6])->diffValuesAndKeys([3, 4, 5]); // [1, 2, 3, 4, 5, 6] keys and values not matching so all entries are different
Collection::instance(['a' => 1, 'b' => 2, 'c' => 3])->diffValuesAndKeys(['a' => 10, 'b' => 2, 'd' => 3]); // ['a' => 1, 'c' => 3] only one matches on both key and value, all others are differentarray_diff_key Computes the difference of arrays using keys for comparison
use Kusabi\Collection\Collection;
Collection::instance([1, 2, 3, 4, 5, 6])->diffKeys([3, 4, 5]); // [3 => 4, 4 => 5, 5 => 6]array_diff_uassoc Computes the difference of arrays with additional index check which is performed by a user supplied callback function
use Kusabi\Collection\Collection;
$a = ['alpha' => 1, 'beta' => 2, 'gamma' => 3];
$b = ['alpha' => 10, 'banana' => 2, 'gamma' => 3];
// Alpha should not match because keys are the same but values are not
// Beta/banana would not normally match because values are the same but keys are different
// gamma will match because key and value both match
$key_compare_function = function ($a, $b) {
// Take only the first letter of the key
$a = substr($a, 0, 1);
$b = substr($b, 0, 1);
return $a <=> $b;
};
// because the key compare function only checks the first letter
// all the keys will match as it will think they are all a, b and c
// So now...
// 'a' should not match because keys are the same but values are not
// 'b' will match because keys and values are the same
// 'g' will match because keys and values are the same
Collection::instance($a)->diffValuesAndKeysCallback($key_compare_function, $b); // ['a' => 1']array_diff_ukey Computes the difference of arrays using a callback function on the keys for comparison
use Kusabi\Collection\Collection;
Collection::instance(['a' => 1, 'b' => 2, 'c' => 3, 'z_something' => 50])->diffKeysCallback(function ($a, $b) {
// Take only the first letter of the key
$a = substr($a, 0, 1);
$b = substr($b, 0, 1);
return $a <=> $b;
}, ['b' => 22, 'c' => 33, 'd' => 44, 'z_else' => 500]); // ['a' => 1]array_diff Computes the difference of arrays
use Kusabi\Collection\Collection;
Collection::instance([1, 2, 3, 4, 5, 6])->diffValues([3, 4, 5]); // [0 => 1, 1 => 2, 5 => 6] Keys are kept
Collection::instance([1, 2, 3, 4, 5, 6])->diffValues([3, 4, 5])->values(); // [1, 2, 5, 6]array_fill_keys Fill an array with values, specifying keys
// todoarray_fill Fill an array with values
use Kusabi\Collection\Collection;
$collection = Collection::fill(0, 10, 'a'); // ['a','a','a','a','a','a','a','a','a','a']array_filter Filters elements of an array using a callback function
use Kusabi\Collection\Collection;
$collection = new Collection([1, 2, 3, 4, 5, 6, null]);
$collection->filter();
$collection->filter(function ($item) {
return $item > 3;
});array_flip Exchanges all keys with their associated values in an array
use Kusabi\Collection\Collection;
$collection = new Collection(['a', 'b', 'c']);
$flipped = $collection->flip(); // ['a' => 0, 'b' => 1, 'c' => 2]
$collection = new Collection(['a', 'b', 'c', 'a']);
$flipped = $collection->flip(); // ['a' => 0, 'b' => 1, 'c' => 2]
$doubleFlipped = $collection->flip()->flip(); // ['a' => 0, 'b' => 1, 'c' => 2]array_intersect_assoc Computes the intersection of arrays with additional index check
use Kusabi\Collection\Collection;
Collection::instance(['a' => 1, 'b' => 2, 'c' => 3])->intersectValuesAndKeys(['b' => 22, 'c' => 3, 'd' => 44]); // ['c' => 3]array_intersect_key Computes the intersection of arrays using keys for comparison
use Kusabi\Collection\Collection;
Collection::instance(['a' => 1, 'b' => 2, 'c' => 3])->intersectKeys(['b' => 22, 'c' => 33, 'd' => 44]); // ['b' => 2, 'c' => 3]array_intersect_uassoc Computes the intersection of arrays with additional index check, compares indexes by a callback function
use Kusabi\Collection\Collection;
$a = ['alpha' => 1, 'beta' => 2, 'gamma' => 3];
$b = ['alpha' => 10, 'banana' => 2, 'gamma' => 3];
// Alpha should not match because keys are the same but values are not
// Beta/banana would not normally match because values are the same but keys are different
// gamma will match because key and value both match
$key_compare_function = function ($a, $b) {
// Take only the first letter of the key
$a = substr($a, 0, 1);
$b = substr($b, 0, 1);
return $a <=> $b;
};
// because the key compare function only checks the first letter
// all the keys will match as it will think they are all a, b and c
// So now...
// 'a' should not match because keys are the same but values are not
// 'b' will match because keys and values are the same
// 'g' will match because keys and values are the same
Collection::instance($a)->intersectValuesAndKeysCallback($key_compare_function, $b); // ['beta' => 2, 'gamma' => 3]array_intersect_ukey Computes the intersection of arrays using a callback function on the keys for comparison
use Kusabi\Collection\Collection;
Collection::instance(['a' => 1, 'b' => 2, 'c' => 3, 'z_something' => 50])->intersectKeysCallback(function ($a, $b) {
// Take only the first letter of the key
$a = substr($a, 0, 1);
$b = substr($b, 0, 1);
return $a <=> $b;
}, ['b' => 22, 'c' => 33, 'd' => 44, 'z_else' => 500]); // ['b' => 2, 'c' => 3, 'z_something' => 50]array_intersect Computes the intersection of arrays
use Kusabi\Collection\Collection;
Collection::instance([1, 2, 3, 4, 5])->intersectValues([1, 99, 3, 100, 5]); // [0 => 1, 2 => 3, 4 => 5] Keep keys
Collection::instance([1, 2, 3, 4, 5])->intersectValues([1, 99, 3, 100, 5])->values(); // [1, 3, 5] Reset keysarray_is_list Checks whether a given array is a list
use Kusabi\Collection\Collection;
Collection::instance(['a', 'b', 'c'])->isList(); // true
Collection::instance(['a' => 1, 'b', 'c'])->isList(); // falsearray_key_exists Checks if the given key or index exists in the array
use Kusabi\Collection\Collection;
$collection = new Collection([
'a' => 1,
'b' => 2,
'c' => [
'a' => 1,
'b' => null,
'c' => 3,
],
]);
$collection->exists('a'); // true
$collection->exists('z'); // false
$collection->exists('c.a'); // true
$collection->exists('c.b'); // true
$collection->exists('c.z'); // falsearray_key_first Gets the first key of an array
use Kusabi\Collection\Collection;
$collection = new Collection(['a' => 1, 'b' => 2, 'c' => 3]);
echo $collection->keys()->first(); // 'a'array_key_last Gets the last key of an array
use Kusabi\Collection\Collection;
$collection = new Collection(['a' => 1, 'b' => 2, 'c' => 3]);
echo $collection->keys()->last(); // 'c'array_keys Return all the keys or a subset of the keys of an array
use Kusabi\Collection\Collection;
$collection = new Collection([
'a' => 1,
'b' => 2,
'c' => [
'a' => 1,
'b' => null,
'c' => 3,
],
]);
$collection->keys(); // ['a', 'b', 'c']
$collection->keys(true); // ['a', 'b', 'c.a', 'c.b', 'c.c']array_map Applies the callback to the elements of the given arrays
use Kusabi\Collection\Collection;
$collection = new Collection([
'a' => 1,
'b' => 2,
'c' => 3
]);
$increased = $collection->map(function ($value) {
return $value * 2;
}); // ['a' => 2, 'b' => 4, 'c' => 6]
$concatenatedKeys = $collection->map(function ($value, $key) {
return $key.'-'.$value;
}); // ['a' => 'a-1', 'b' => 'b-2', 'c' => 'c-3']array_merge_recursive Merge one or more arrays recursively
// todoarray_merge Merge one or more arrays
use Kusabi\Collection\Collection;
$a = new Collection(['a' => 1, 'b' => 2, 'c' => 3]);
$b = ['c' => 99, 'd' => 98, 'e' => 97];
$a->merge($b); // ['a' => 1, 'b' => 2, 'c' => 99, 'd' => 98, 'e' => 97]
$a = new Collection(['a' => 1, 'b' => 2, 'c' => 3]);
$b = new Collection(['c' => 99, 'd' => 98, 'e' => 97]);
$a->merge($b); // ['a' => 1, 'b' => 2, 'c' => 99, 'd' => 98, 'e' => 97]array_multisort Sort multiple or multi-dimensional arrays
// todoarray_pad Pad array to the specified length with a value
use Kusabi\Collection\Collection;
$a = new Collection([1, 2, 3]);
$b = $a->pad(10, 'a'); // [1, 2, 3, 'a', 'a', 'a', 'a', 'a', 'a', 'a']array_pop Pop the element off the end of array
use Kusabi\Collection\Collection;
$collection = new Collection([1, 2, 3, 4]);
$popped = $collection->pop(); // [1, 2, 3]
echo $popped; // 4array_product Calculate the product of values in an array
// todoarray_push Push one or more elements onto the end of array
use Kusabi\Collection\Collection;
$collection = new Collection([1, 2, 3, 4]);
$collection->push(5, 6, 7, 8); // [1, 2, 3, 4, 5, 6, 7, 8]array_rand Pick one or more random keys out of an array
// todoarray_reduce Iteratively reduce the array to a single value using a callback function
use Kusabi\Collection\Collection;
$ten_factorial = Collection::range(1, 10)->reduce(function ($carry, $value) {
return $carry * $value;
}, 1); // 3628800array_replace_recursive Replaces elements from passed arrays into the first array recursively
// todoarray_replace Replaces elements from passed arrays into the first array
// todoarray_reverse Return an array with elements in reverse order
use Kusabi\Collection\Collection;
$collection = new Collection([
'a' => 1,
'b' => 2,
'c' => 3
]);
$reversedCopy = $collection->reverse(); // ['c' => 3, 'b' => 2, 'a' => 1]array_search Searches the array for a given value and returns the first corresponding key if successful
// todoarray_shift Shift an element off the beginning of array
use Kusabi\Collection\Collection;
$collection = new Collection([1, 2, 3, 4]);
$shifted = $collection->shift(); // [2, 3, 4]
echo $shifted; // 1array_slice Extract a slice of the array
use Kusabi\Collection\Collection;
Collection::range('a', 'j')->slice(2, 4); // ['c', 'd']array_splice Remove a portion of the array and replace it with something else
// todoarray_sum Calculate the sum of values in an array
use Kusabi\Collection\Collection;
$sum = Collection::instance([1, 2, 3])->sum(); // 6
$sum = Collection::range(1, 100)->sum(); // 5050array_udiff_assoc Computes the difference of arrays with additional index check, compares data by a callback function
// todoarray_udiff_uassoc Computes the difference of arrays with additional index check, compares data and indexes by a callback function
// todoarray_udiff Computes the difference of arrays by using a callback function for data comparison
// todoarray_uintersect_assoc Computes the intersection of arrays with additional index check, compares data by a callback function
// todoarray_uintersect_uassoc Computes the intersection of arrays with additional index check, compares data and indexes by separate callback functions
// todoarray_uintersect Computes the intersection of arrays, compares data by a callback function
// todoarray_unique Removes duplicate values from an array
// todoarray_unshift Prepend one or more elements to the beginning of an array
use Kusabi\Collection\Collection;
$collection = new Collection([1, 2, 3, 4]);
$collection->unshift(5, 6, 7, 8); // [5, 6, 7, 8, 1, 2, 3, 4]array_values Return all the values of an array
use Kusabi\Collection\Collection;
$collection = new Collection(['a' => 1, 'b' => 2, 'c' => 3]);
$collection->values(5, 6, 7, 8); // [1, 2, 3]array_walk_recursive Apply a user function recursively to every member of an array
// todoarray_walk Apply a user supplied function to every member of an array
// todoarray Create an array
arsort Sort an array in descending order and maintain index association
use Kusabi\Collection\Collection;
Collection::instance([1, 2, 3, 4, 5])->sortValues(SORT_DESC);
Collection::instance([1, 2, 3, 4, 5])->sortValues()->reverse();
Collection::instance([1, 2, 3, 4, 5])->sort()->reverse();asort Sort an array in ascending order and maintain index association
use Kusabi\Collection\Collection;
Collection::instance([5, 4, 3, 2, 1])->sortValues();
Collection::instance([5, 4, 3, 2, 1])->sort();compact Create array containing variables and their values
// todocount Counts all elements in an array or in a Countable object
use Kusabi\Collection\Collection;
$collection = new Collection([1, 2, 3]);
count($collection); // 3
$collection->count(); // 3current Return the current element in an array
// todoeach Return the current key and value pair from an array and advance the array cursor
// todoend Set the internal pointer of an array to its last element
// todoextract Import variables into the current symbol table from an array
use Kusabi\Collection\Collection;
$collection = new Collection(['a' => 1, 'b' => 2]);
extract($collection->array()); // No way to get the new variables into the caller scope. If we have collection->extract() then the variables will be created into the method scopeimplode Join array elements with a string
use Kusabi\Collection\Collection;
echo Collection::instance('a', 'b', 'c')->implode(', '); // "a, b, c"
echo Collection::instance('a', 'b', 'c')->implode(', ', ' and '); // "a, b and c"in_array Checks if a value exists in an array
use Kusabi\Collection\Collection;
$collection = new Collection([4, 5, 6]);
$collection->contains(5);key_exists Alias of array_key_exists
use Kusabi\Collection\Collection;
$collection = new Collection([
'a' => 1,
'b' => 2,
'c' => [
'a' => 1,
'b' => null,
'c' => 3,
],
]);
$collection->exists('a'); // true
$collection->exists('z'); // false
$collection->exists('c.a'); // true
$collection->exists('c.b'); // true
$collection->exists('c.z'); // falsekey Fetch a key from an array
// todokrsort Sort an array by key in descending order
use Kusabi\Collection\Collection;
Collection::instance(['a' => 2, 'b' => 2, 'c' => 2, 'd' => 2, 'e' => 2])->sortKeys(SORT_DESC);
Collection::instance(['a' => 2, 'b' => 2, 'c' => 2, 'd' => 2, 'e' => 2])->sortKeys()->reverse();ksort Sort an array by key in ascending order
use Kusabi\Collection\Collection;
Collection::instance(['a' => 2, 'b' => 2, 'c' => 2, 'd' => 2, 'e' => 2])->sortKeys();list Assign variables as if they were an array
// todonatcasesort Sort an array using a case insensitive "natural order" algorithm
use Kusabi\Collection\Collection;
// Keep keys
Collection::instance([5, 4, 3, 2, 1])->sortValues(SORT_ASC, true, SORT_NATURAL | SORT_FLAG_CASE);
// Lose keys
Collection::instance([5, 4, 3, 2, 1])->sortValues(SORT_ASC, false, SORT_NATURAL | SORT_FLAG_CASE);natsort Sort an array using a "natural order" algorithm
use Kusabi\Collection\Collection;
// Keep keys
Collection::instance([5, 4, 3, 2, 1])->sortValues(SORT_ASC, true, SORT_NATURAL);
// Lose keys
Collection::instance([5, 4, 3, 2, 1])->sortValues(SORT_ASC, false, SORT_NATURAL);next Advance the internal pointer of an array
// todopos Alias of current
// todoprev Rewind the internal array pointer
// todorange Create an array containing a range of elements
use Kusabi\Collection\Collection;
$numbers = Collection::range(0, 100);
$even = Collection::range(0, 100, 2);
$alphabet = Collection::range('a', 'z');reset Set the internal pointer of an array to its first element
// todorsort Sort an array in descending order (loses keys)
use Kusabi\Collection\Collection;
Collection::instance([1, 2, 3, 4, 5])->sortValues(SORT_DESC, false);
Collection::instance([1, 2, 3, 4, 5])->sortValues(SORT_ASC, false)->reverse();
Collection::instance([1, 2, 3, 4, 5])->sort()->reverse()->values();shuffle Shuffle an array
// todosizeof Alias of count
use Kusabi\Collection\Collection;
$collection = new Collection([1, 2, 3]);
count($collection); // 3
$collection->count(); // 3sort Sort an array in ascending order (loses keys)
use Kusabi\Collection\Collection;
Collection::instance([5, 4, 3, 2, 1])->sortValues(SORT_ASC, false);
Collection::instance([5, 4, 3, 2, 1])->sort()->values();uasort Sort an array with a user-defined comparison function and maintain index association
use Kusabi\Collection\Collection;
$collection = new Collection([5, 4, 3, 2, 1]);
$collection->sortValuesCallback(function ($a, $b) {
return $a <=> $b;
});uksort Sort an array by keys using a user-defined comparison function
$collection = new Collection(['e' => 2, 'd' => 2, 'c' => 2, 'b' => 2, 'a' => 2]);
$collection->sortKeysCallback(function ($a, $b) {
return $a <=> $b;
});usort Sort an array by values using a user-defined comparison function (loses keys)
use Kusabi\Collection\Collection;
$collection = new Collection([5, 4, 3, 2, 1]);
$collection->sortValuesCallback(function ($a, $b) {
return $a <=> $b;
}, false);