Add `binarySearch()` and `binarySearchBy()`. Refactor code.
This commit is contained in:
parent
7c9fda5c64
commit
1b2d443697
|
@ -97,21 +97,21 @@ ZEND_BEGIN_ARG_INFO(copy_of_arginfo, 0)
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO(copy_of_range_arginfo, 0)
|
ZEND_BEGIN_ARG_INFO(copy_of_range_arginfo, 0)
|
||||||
ZEND_ARG_TYPE_INFO(0, from_idx, IS_LONG, 0)
|
ZEND_ARG_TYPE_INFO(0, from_index, IS_LONG, 0)
|
||||||
ZEND_ARG_TYPE_INFO(0, num_elements, IS_LONG, 0)
|
ZEND_ARG_TYPE_INFO(0, to_index, IS_LONG, 0)
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO(fill_arginfo, 0)
|
ZEND_BEGIN_ARG_INFO(fill_arginfo, 0)
|
||||||
ZEND_ARG_INFO(0, element)
|
ZEND_ARG_INFO(0, element)
|
||||||
ZEND_ARG_TYPE_INFO(0, from_index, IS_LONG, 0)
|
ZEND_ARG_TYPE_INFO(0, from_index, IS_LONG, 0)
|
||||||
ZEND_ARG_TYPE_INFO(0, num_elements, IS_LONG, 0)
|
ZEND_ARG_TYPE_INFO(0, to_index, IS_LONG, 0)
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO(binary_search_arginfo, 0)
|
ZEND_BEGIN_ARG_INFO(binary_search_arginfo, 0)
|
||||||
ZEND_ARG_INFO(0, element)
|
ZEND_ARG_INFO(0, element)
|
||||||
ZEND_ARG_TYPE_INFO(0, flags, IS_LONG, 0)
|
ZEND_ARG_TYPE_INFO(0, flags, IS_LONG, 0)
|
||||||
ZEND_ARG_TYPE_INFO(0, from_index, IS_LONG, 0)
|
ZEND_ARG_TYPE_INFO(0, from_index, IS_LONG, 0)
|
||||||
ZEND_ARG_TYPE_INFO(0, num_elements, IS_LONG, 0)
|
ZEND_ARG_TYPE_INFO(0, to_index, IS_LONG, 0)
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO(binary_search_by_arginfo, 0)
|
ZEND_BEGIN_ARG_INFO(binary_search_by_arginfo, 0)
|
||||||
|
@ -119,7 +119,7 @@ ZEND_BEGIN_ARG_INFO(binary_search_by_arginfo, 0)
|
||||||
ZEND_ARG_CALLABLE_INFO(0, selector, 0)
|
ZEND_ARG_CALLABLE_INFO(0, selector, 0)
|
||||||
ZEND_ARG_TYPE_INFO(0, flags, IS_LONG, 0)
|
ZEND_ARG_TYPE_INFO(0, flags, IS_LONG, 0)
|
||||||
ZEND_ARG_TYPE_INFO(0, from_index, IS_LONG, 0)
|
ZEND_ARG_TYPE_INFO(0, from_index, IS_LONG, 0)
|
||||||
ZEND_ARG_TYPE_INFO(0, num_elements, IS_LONG, 0)
|
ZEND_ARG_TYPE_INFO(0, to_index, IS_LONG, 0)
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO(chuncked_arginfo, 0)
|
ZEND_BEGIN_ARG_INFO(chuncked_arginfo, 0)
|
||||||
|
|
|
@ -75,6 +75,8 @@
|
||||||
PHP_COLLECTIONS_ERROR(E_WARNING, "Elements should be int or double")
|
PHP_COLLECTIONS_ERROR(E_WARNING, "Elements should be int or double")
|
||||||
#define ERR_BAD_GROUP() \
|
#define ERR_BAD_GROUP() \
|
||||||
PHP_COLLECTIONS_ERROR(E_WARNING, "Group value must be array")
|
PHP_COLLECTIONS_ERROR(E_WARNING, "Group value must be array")
|
||||||
|
#define ERR_NOT_PACKED() \
|
||||||
|
PHP_COLLECTIONS_ERROR(E_WARNING, "The array should be packed")
|
||||||
#define ERR_SILENCED()
|
#define ERR_SILENCED()
|
||||||
|
|
||||||
#define ELEMENTS_VALIDATE(elements, err, err_then) \
|
#define ELEMENTS_VALIDATE(elements, err, err_then) \
|
||||||
|
@ -147,6 +149,15 @@ static zend_always_inline zend_object* create_pair_obj()
|
||||||
return create_object(collections_pair_ce, &std_object_handlers);
|
return create_object(collections_pair_ce, &std_object_handlers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static zend_always_inline void array_release(zend_array* ht)
|
||||||
|
{
|
||||||
|
if (GC_REFCOUNT(ht) > 1) {
|
||||||
|
GC_DELREF(ht);
|
||||||
|
} else {
|
||||||
|
zend_array_destroy(ht);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static zend_always_inline zend_array* array_group_fetch(zend_array* ht, zval* key)
|
static zend_always_inline zend_array* array_group_fetch(zend_array* ht, zval* key)
|
||||||
{
|
{
|
||||||
zend_array* group = NULL;
|
zend_array* group = NULL;
|
||||||
|
@ -351,6 +362,25 @@ static zend_always_inline compare_func_t compare_func_init(
|
||||||
return reverse ? bucket_reverse_compare_regular : bucket_compare_regular;
|
return reverse ? bucket_reverse_compare_regular : bucket_compare_regular;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static zend_always_inline zend_long binary_search(Bucket* ref, zval* val,
|
||||||
|
zend_long from_idx, zend_long to_idx, compare_func_t cmp)
|
||||||
|
{
|
||||||
|
zend_long low = from_idx;
|
||||||
|
zend_long high = to_idx - 1;
|
||||||
|
while (low <= high) {
|
||||||
|
zend_long mid = (low + high) >> 1;
|
||||||
|
int result = cmp(&ref[mid].val, val);
|
||||||
|
if (result == 1) {
|
||||||
|
high = mid - 1;
|
||||||
|
} else if (result == -1) {
|
||||||
|
low = mid + 1;
|
||||||
|
} else {
|
||||||
|
return mid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -(low + 1);
|
||||||
|
}
|
||||||
|
|
||||||
static zend_always_inline void array_sort_by(zend_array* ht)
|
static zend_always_inline void array_sort_by(zend_array* ht)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
@ -879,12 +909,95 @@ PHP_METHOD(Collection, average)
|
||||||
|
|
||||||
PHP_METHOD(Collection, binarySearch)
|
PHP_METHOD(Collection, binarySearch)
|
||||||
{
|
{
|
||||||
|
zval* element;
|
||||||
|
zend_long flags = 0;
|
||||||
|
zend_long from_idx = 0;
|
||||||
|
zend_array* current = THIS_COLLECTION;
|
||||||
|
uint32_t num_elements = zend_hash_num_elements(current);
|
||||||
|
zend_long to_idx = num_elements;
|
||||||
|
ZEND_PARSE_PARAMETERS_START(1, 4)
|
||||||
|
Z_PARAM_ZVAL(element)
|
||||||
|
Z_PARAM_OPTIONAL
|
||||||
|
Z_PARAM_LONG(flags)
|
||||||
|
Z_PARAM_LONG(from_idx)
|
||||||
|
Z_PARAM_LONG(to_idx)
|
||||||
|
ZEND_PARSE_PARAMETERS_END();
|
||||||
|
if (UNEXPECTED(!HT_IS_PACKED(current))) {
|
||||||
|
ERR_NOT_PACKED();
|
||||||
|
RETURN_NULL();
|
||||||
|
}
|
||||||
|
if (UNEXPECTED(from_idx < 0)) {
|
||||||
|
ERR_BAD_INDEX();
|
||||||
|
RETURN_NULL();
|
||||||
|
}
|
||||||
|
if (to_idx > num_elements) {
|
||||||
|
to_idx = num_elements;
|
||||||
|
}
|
||||||
|
if (UNEXPECTED(to_idx < from_idx)) {
|
||||||
|
ERR_BAD_SIZE();
|
||||||
|
RETURN_NULL();
|
||||||
|
}
|
||||||
|
compare_func_t cmp;
|
||||||
|
ZEND_HASH_FOREACH_VAL(current, zval* val)
|
||||||
|
cmp = compare_func_init(val, 0, flags);
|
||||||
|
break;
|
||||||
|
ZEND_HASH_FOREACH_END();
|
||||||
|
RETVAL_LONG(binary_search(current->arData, element, from_idx, to_idx, cmp));
|
||||||
}
|
}
|
||||||
|
|
||||||
PHP_METHOD(Collection, binarySearchBy)
|
PHP_METHOD(Collection, binarySearchBy)
|
||||||
{
|
{
|
||||||
|
zval* element;
|
||||||
|
zend_fcall_info fci;
|
||||||
|
zend_fcall_info_cache fcc;
|
||||||
|
zend_long flags = 0;
|
||||||
|
zend_long from_idx = 0;
|
||||||
|
zend_array* current = THIS_COLLECTION;
|
||||||
|
uint32_t num_elements = zend_hash_num_elements(current);
|
||||||
|
zend_long to_idx = num_elements;
|
||||||
|
ZEND_PARSE_PARAMETERS_START(2, 5)
|
||||||
|
Z_PARAM_ZVAL(element)
|
||||||
|
Z_PARAM_FUNC(fci, fcc)
|
||||||
|
Z_PARAM_OPTIONAL
|
||||||
|
Z_PARAM_LONG(flags)
|
||||||
|
Z_PARAM_LONG(from_idx)
|
||||||
|
Z_PARAM_LONG(to_idx)
|
||||||
|
ZEND_PARSE_PARAMETERS_END();
|
||||||
|
if (UNEXPECTED(!HT_IS_PACKED(current))) {
|
||||||
|
ERR_NOT_PACKED();
|
||||||
|
RETURN_NULL();
|
||||||
|
}
|
||||||
|
if (UNEXPECTED(from_idx < 0)) {
|
||||||
|
ERR_BAD_INDEX();
|
||||||
|
RETURN_NULL();
|
||||||
|
}
|
||||||
|
if (to_idx > num_elements) {
|
||||||
|
to_idx = num_elements;
|
||||||
|
}
|
||||||
|
if (UNEXPECTED(to_idx < from_idx)) {
|
||||||
|
ERR_BAD_SIZE();
|
||||||
|
RETURN_NULL();
|
||||||
|
}
|
||||||
|
INIT_FCI(&fci, 2);
|
||||||
|
uint32_t range = to_idx - from_idx;
|
||||||
|
Bucket* ref = (Bucket*)malloc(range * sizeof(Bucket));
|
||||||
|
compare_func_t cmp = NULL;
|
||||||
|
uint32_t idx = 0;
|
||||||
|
Bucket* bucket = current->arData + from_idx;
|
||||||
|
Bucket* end = current->arData + to_idx;
|
||||||
|
for (; bucket < end; ++bucket) {
|
||||||
|
CALLBACK_KEYVAL_INVOKE(params, bucket);
|
||||||
|
memcpy(&ref[idx++].val, &bucket->val, sizeof(zval));
|
||||||
|
if (UNEXPECTED(cmp == NULL)) {
|
||||||
|
cmp = compare_func_init(&retval, 0, flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
zend_long result = binary_search(ref, element, 0, range, cmp);
|
||||||
|
RETVAL_LONG(result < 0 ? result - from_idx : result + from_idx);
|
||||||
|
for (idx = 0; idx < range; ++idx) {
|
||||||
|
zval_ptr_dtor(&ref[idx].val);
|
||||||
|
}
|
||||||
|
free(ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
PHP_METHOD(Collection, chunked)
|
PHP_METHOD(Collection, chunked)
|
||||||
|
@ -928,6 +1041,7 @@ PHP_METHOD(Collection, chunked)
|
||||||
if (transform) {
|
if (transform) {
|
||||||
ZVAL_LONG(¶ms[1], num_chunks++);
|
ZVAL_LONG(¶ms[1], num_chunks++);
|
||||||
zend_call_function(&fci, &fcc);
|
zend_call_function(&fci, &fcc);
|
||||||
|
array_release(chunk);
|
||||||
zend_hash_next_index_insert(chunked, &retval);
|
zend_hash_next_index_insert(chunked, &retval);
|
||||||
} else {
|
} else {
|
||||||
zend_hash_next_index_insert(chunked, ¶ms[0]);
|
zend_hash_next_index_insert(chunked, ¶ms[0]);
|
||||||
|
@ -939,6 +1053,7 @@ PHP_METHOD(Collection, chunked)
|
||||||
if (transform) {
|
if (transform) {
|
||||||
ZVAL_LONG(¶ms[1], num_chunks++);
|
ZVAL_LONG(¶ms[1], num_chunks++);
|
||||||
zend_call_function(&fci, &fcc);
|
zend_call_function(&fci, &fcc);
|
||||||
|
array_release(chunk);
|
||||||
zend_hash_next_index_insert(chunked, &retval);
|
zend_hash_next_index_insert(chunked, &retval);
|
||||||
} else {
|
} else {
|
||||||
zend_hash_next_index_insert(chunked, ¶ms[0]);
|
zend_hash_next_index_insert(chunked, ¶ms[0]);
|
||||||
|
@ -1115,20 +1230,21 @@ PHP_METHOD(Collection, copyOf)
|
||||||
|
|
||||||
PHP_METHOD(Collection, copyOfRange)
|
PHP_METHOD(Collection, copyOfRange)
|
||||||
{
|
{
|
||||||
zend_long from_idx, num_elements;
|
zend_long from_idx, to_idx;
|
||||||
ZEND_PARSE_PARAMETERS_START(2, 2)
|
ZEND_PARSE_PARAMETERS_START(2, 2)
|
||||||
Z_PARAM_LONG(from_idx)
|
Z_PARAM_LONG(from_idx)
|
||||||
Z_PARAM_LONG(num_elements)
|
Z_PARAM_LONG(to_idx)
|
||||||
ZEND_PARSE_PARAMETERS_END();
|
ZEND_PARSE_PARAMETERS_END();
|
||||||
if (from_idx < 0) {
|
if (UNEXPECTED(from_idx < 0)) {
|
||||||
ERR_BAD_INDEX();
|
ERR_BAD_INDEX();
|
||||||
RETURN_NULL();
|
RETURN_NULL();
|
||||||
}
|
}
|
||||||
if (num_elements < 0) {
|
if (UNEXPECTED(to_idx < from_idx)) {
|
||||||
ERR_BAD_SIZE();
|
ERR_BAD_SIZE();
|
||||||
RETURN_NULL();
|
RETURN_NULL();
|
||||||
}
|
}
|
||||||
zend_array* current = THIS_COLLECTION;
|
zend_array* current = THIS_COLLECTION;
|
||||||
|
uint32_t num_elements = to_idx - from_idx;
|
||||||
ARRAY_NEW(new_collection, num_elements);
|
ARRAY_NEW(new_collection, num_elements);
|
||||||
zend_bool packed = HT_IS_PACKED(current);
|
zend_bool packed = HT_IS_PACKED(current);
|
||||||
Bucket* bucket = current->arData;
|
Bucket* bucket = current->arData;
|
||||||
|
@ -1316,14 +1432,23 @@ PHP_METHOD(Collection, fill)
|
||||||
zval* element;
|
zval* element;
|
||||||
zend_long from_idx = 0;
|
zend_long from_idx = 0;
|
||||||
zend_array* current = THIS_COLLECTION;
|
zend_array* current = THIS_COLLECTION;
|
||||||
SEPARATE_CURRENT_COLLECTION(current);
|
zend_long to_idx = zend_hash_num_elements(current);
|
||||||
zend_long num_elements = zend_hash_num_elements(current - from_idx);
|
|
||||||
ZEND_PARSE_PARAMETERS_START(1, 3)
|
ZEND_PARSE_PARAMETERS_START(1, 3)
|
||||||
Z_PARAM_ZVAL(element)
|
Z_PARAM_ZVAL(element)
|
||||||
Z_PARAM_OPTIONAL
|
Z_PARAM_OPTIONAL
|
||||||
Z_PARAM_LONG(from_idx)
|
Z_PARAM_LONG(from_idx)
|
||||||
Z_PARAM_LONG(num_elements)
|
Z_PARAM_LONG(to_idx)
|
||||||
ZEND_PARSE_PARAMETERS_END();
|
ZEND_PARSE_PARAMETERS_END();
|
||||||
|
if (UNEXPECTED(from_idx < 0)) {
|
||||||
|
ERR_BAD_INDEX();
|
||||||
|
RETURN_NULL();
|
||||||
|
}
|
||||||
|
if (UNEXPECTED(to_idx < from_idx)) {
|
||||||
|
ERR_BAD_SIZE();
|
||||||
|
RETURN_NULL();
|
||||||
|
}
|
||||||
|
SEPARATE_CURRENT_COLLECTION(current);
|
||||||
|
uint32_t num_elements = to_idx - from_idx;
|
||||||
Bucket* bucket = current->arData + from_idx;
|
Bucket* bucket = current->arData + from_idx;
|
||||||
Bucket* end = bucket + current->nNumUsed;
|
Bucket* end = bucket + current->nNumUsed;
|
||||||
for (; num_elements > 0 && bucket < end; ++bucket, --num_elements) {
|
for (; num_elements > 0 && bucket < end; ++bucket, --num_elements) {
|
||||||
|
|
|
@ -102,10 +102,10 @@ class Collection implements ArrayAccess, Countable
|
||||||
* @param mixed $element
|
* @param mixed $element
|
||||||
* @param int $flags[optional]
|
* @param int $flags[optional]
|
||||||
* @param int $from_index[optional]
|
* @param int $from_index[optional]
|
||||||
* @param int $num_elements[optional]
|
* @param int $to_index[optional]
|
||||||
* @return int|null
|
* @return int|null
|
||||||
*/
|
*/
|
||||||
function binarySearch($element, $flags, $from_index, $num_elements) {}
|
function binarySearch($element, $flags, $from_index, $to_index) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Searches the array or the range of the array for the provided element using the
|
* Searches the array or the range of the array for the provided element using the
|
||||||
|
@ -119,10 +119,25 @@ class Collection implements ArrayAccess, Countable
|
||||||
* @param callable $selector ($value, $key) -> $new_value
|
* @param callable $selector ($value, $key) -> $new_value
|
||||||
* @param int $flags[optional]
|
* @param int $flags[optional]
|
||||||
* @param int $from_index[optional]
|
* @param int $from_index[optional]
|
||||||
* @param int $num_elements[optional]
|
* @param int $to_index[optional]
|
||||||
* @return int|null
|
* @return int|null
|
||||||
*/
|
*/
|
||||||
function binarySearchBy($element, $selector, $flags, $from_index, $num_elements) {}
|
function binarySearchBy($element, $selector, $flags, $from_index, $to_index) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Searches the array or the range of the array for the provided element using the
|
||||||
|
* binary search algorithm.
|
||||||
|
*
|
||||||
|
* The array is expected to be packed and sorted into ascending order according to
|
||||||
|
* the specified comparator, otherwise the result is undefined.
|
||||||
|
*
|
||||||
|
* @param mixed $element
|
||||||
|
* @param callable $comparator (Pair($key, $value), Pair($key, $value)) -> int
|
||||||
|
* @param int $from_index[optional]
|
||||||
|
* @param int $to_index[optional]
|
||||||
|
* @return int|null
|
||||||
|
*/
|
||||||
|
function binarySearchWith($element, $comparator, $from_index, $to_index) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Splits this collection into a collection of arrays each not exceeding the given size.
|
* Splits this collection into a collection of arrays each not exceeding the given size.
|
||||||
|
@ -187,10 +202,10 @@ class Collection implements ArrayAccess, Countable
|
||||||
* Returns new collection which is a copy of range of original collection.
|
* Returns new collection which is a copy of range of original collection.
|
||||||
*
|
*
|
||||||
* @param int $from_index
|
* @param int $from_index
|
||||||
* @param int $num_elements
|
* @param int $to_index
|
||||||
* @return Collection
|
* @return Collection
|
||||||
*/
|
*/
|
||||||
function copyOfRange($from_index, $num_elements) {}
|
function copyOfRange($from_index, $to_index) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the number of elements in this collection.
|
* Returns the number of elements in this collection.
|
||||||
|
@ -260,10 +275,10 @@ class Collection implements ArrayAccess, Countable
|
||||||
*
|
*
|
||||||
* @param mixed $element
|
* @param mixed $element
|
||||||
* @param int $from_index[optional]
|
* @param int $from_index[optional]
|
||||||
* @param int $num_elements[optional]
|
* @param int $to_index[optional]
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
function fill($element, $from_index, $num_elements) {}
|
function fill($element, $from_index, $to_index) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a collection containing only elements matching the given predicate.
|
* Returns a collection containing only elements matching the given predicate.
|
||||||
|
|
|
@ -7,8 +7,8 @@ $array = [3, 7, 6, 9, 2];
|
||||||
// An associative array, however, Collection::copyOfRange() still works,
|
// An associative array, however, Collection::copyOfRange() still works,
|
||||||
// and string keys will be preserved.
|
// and string keys will be preserved.
|
||||||
$array1 = ['a' => 'b', 'c', 'd' => 'e'];
|
$array1 = ['a' => 'b', 'c', 'd' => 'e'];
|
||||||
$array2 = Collection::init($array)->copyOfRange(2, 4)->toArray();
|
$array2 = Collection::init($array)->copyOfRange(2, 6)->toArray();
|
||||||
$array3 = Collection::init($array1)->copyOfRange(1, 2)->toArray();
|
$array3 = Collection::init($array1)->copyOfRange(1, 3)->toArray();
|
||||||
if ($array2 != array_slice($array, 2, 4) || $array3 != array_slice($array1, 1, 2)) {
|
if ($array2 != array_slice($array, 2, 4) || $array3 != array_slice($array1, 1, 2)) {
|
||||||
echo 'Collection::copyOfRange() failed.', PHP_EOL;
|
echo 'Collection::copyOfRange() failed.', PHP_EOL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ Test Collection::fill().
|
||||||
<?php
|
<?php
|
||||||
$array = ['foo', 'bar' => 'baz', 1, 2, 3];
|
$array = ['foo', 'bar' => 'baz', 1, 2, 3];
|
||||||
$collection = Collection::init($array);
|
$collection = Collection::init($array);
|
||||||
$collection->fill('t', 1, 3);
|
$collection->fill('t', 1, 4);
|
||||||
$array1 = ['foo', 'bar' => 't', 't', 't', 3];
|
$array1 = ['foo', 'bar' => 't', 't', 't', 3];
|
||||||
$collection1 = Collection::init($array);
|
$collection1 = Collection::init($array);
|
||||||
$collection1->fill(0);
|
$collection1->fill(0);
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
--TEST--
|
||||||
|
Test Collection::binarySearch().
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
$array = [];
|
||||||
|
$size = random_int(20, 30);
|
||||||
|
for ($i = 0; $i < 50; ++$i) {
|
||||||
|
$array[] = random_int(100, 200);
|
||||||
|
}
|
||||||
|
$array = array_unique($array);
|
||||||
|
sort($array);
|
||||||
|
$idx = random_int(0, count($array) - 1);
|
||||||
|
$which = $array[$idx];
|
||||||
|
$from = random_int(0, $idx);
|
||||||
|
$to = random_int($idx, count($array));
|
||||||
|
$collection = Collection::init($array);
|
||||||
|
if ($collection->binarySearch($which, 0, $from, $to) != $idx) {
|
||||||
|
echo 'Collection::binarySearch() failed.', PHP_EOL;
|
||||||
|
}
|
||||||
|
$array = array_map(function ($value) {
|
||||||
|
return [$value];
|
||||||
|
}, $array);
|
||||||
|
$selector = function ($value) {
|
||||||
|
return $value[0];
|
||||||
|
};
|
||||||
|
if ($collection->binarySearchBy($which, $selector, 0, $from, $to) != $idx) {
|
||||||
|
echo 'Collection::binarySearchBy() failed.', PHP_EOL;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
Reference in New Issue