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/collections
Or 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/phpunit
Before 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 fix
Before pushing, please ensure you have run the static analyses tool.
vendor/bin/phan
Before 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 --gui
This 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 different
array_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
// todo
array_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 keys
array_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(); // false
array_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'); // false
array_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
// todo
array_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
// todo
array_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; // 4
array_product Calculate the product of values in an array
// todo
array_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
// todo
array_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); // 3628800
array_replace_recursive Replaces elements from passed arrays into the first array recursively
// todo
array_replace Replaces elements from passed arrays into the first array
// todo
array_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
// todo
array_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; // 1
array_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
// todo
array_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(); // 5050
array_udiff_assoc Computes the difference of arrays with additional index check, compares data by a callback function
// todo
array_udiff_uassoc Computes the difference of arrays with additional index check, compares data and indexes by a callback function
// todo
array_udiff Computes the difference of arrays by using a callback function for data comparison
// todo
array_uintersect_assoc Computes the intersection of arrays with additional index check, compares data by a callback function
// todo
array_uintersect_uassoc Computes the intersection of arrays with additional index check, compares data and indexes by separate callback functions
// todo
array_uintersect Computes the intersection of arrays, compares data by a callback function
// todo
array_unique Removes duplicate values from an array
// todo
array_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
// todo
array_walk Apply a user supplied function to every member of an array
// todo
array 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
// todo
count 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(); // 3
current Return the current element in an array
// todo
each Return the current key and value pair from an array and advance the array cursor
// todo
end Set the internal pointer of an array to its last element
// todo
extract 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 scope
implode 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'); // false
key Fetch a key from an array
// todo
krsort 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
// todo
natcasesort 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
// todo
pos Alias of current
// todo
prev Rewind the internal array pointer
// todo
range 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
// todo
rsort 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
// todo
sizeof Alias of count
use Kusabi\Collection\Collection;
$collection = new Collection([1, 2, 3]);
count($collection); // 3
$collection->count(); // 3
sort 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);