Skip to content

Commit

Permalink
Refactor anonymous functions to private methods.
Browse files Browse the repository at this point in the history
  • Loading branch information
pfrenssen authored and sebastianbergmann committed Jun 7, 2018
1 parent 703449e commit 84d01bb
Showing 1 changed file with 83 additions and 85 deletions.
168 changes: 83 additions & 85 deletions src/Framework/Constraint/ArraySubset.php
Expand Up @@ -59,97 +59,16 @@ public function __construct(iterable $subset, bool $strict = false)
*/
public function evaluate($other, $description = '', $returnResult = false)
{
// Anonymous function that checks whether the given array is
// associative.
$is_associative = function (array $array): bool {
return \array_reduce(\array_keys($array), function (bool $carry, $key): bool {
return $carry || \is_string($key);
}, false);
};

// Anonymous function that compares the two given values using either
// strict or loose comparisons.
$strict = $this->strict;
$compare = function ($first, $second) use ($strict): bool {
return $strict ? $first === $second : $first == $second;
};

// Anonymous function that sorts the given multidimensional array.
$deep_sort = function (array &$array) use (&$deep_sort, $is_associative): void {
foreach ($array as &$value) {
if (\is_array($value)) {
$deep_sort($value);
}
}

if ($is_associative($array)) {
\ksort($array);
} else {
\sort($array);
}
};

$array_intersect_recursive = function (array $array, array $subset) use (&$array_intersect_recursive, $is_associative, $compare): array {
$intersect = [];

if ($is_associative($subset)) {
// If the subset is an associative array, get the intersection
// while preserving the keys.
foreach ($subset as $key => $subset_value) {
if (\array_key_exists($key, $array)) {
$array_value = $array[$key];

if (\is_array($subset_value) && \is_array($array_value)) {
$intersect[$key] = $array_intersect_recursive($array_value, $subset_value);
} elseif ($compare($subset_value, $array_value)) {
$intersect[$key] = $array_value;
}
}
}
} else {
// If the subset is an indexed array, loop over all entries in
// the haystack and check if they match the ones in the subset.
foreach ($array as $array_value) {
if (\is_array($array_value)) {
foreach ($subset as $key => $subset_value) {
if (\is_array($subset_value)) {
$recursed = $array_intersect_recursive($array_value, $subset_value);

if (!empty($recursed)) {
$intersect[$key] = $recursed;

break;
}
}
}
} else {
foreach ($subset as $key => $subset_value) {
if (!\is_array($subset_value) && $compare(
$subset_value,
$array_value
)) {
$intersect[$key] = $array_value;

break;
}
}
}
}
}

return $intersect;
};

//type cast $other & $this->subset as an array to allow
//support in standard array functions.
$other = $this->toArray($other);
$this->subset = $this->toArray($this->subset);

$intersect = $array_intersect_recursive($other, $this->subset);
$deep_sort($intersect);
$deep_sort($this->subset);
$intersect = $this->arrayIntersectRecursive($other, $this->subset);
$this->deepSort($intersect);
$this->deepSort($this->subset);

$result = $compare($intersect, $this->subset);
$result = $this->compare($intersect, $this->subset);

if ($returnResult) {
return $result;
Expand Down Expand Up @@ -209,4 +128,83 @@ private function toArray(iterable $other): array
// Keep BC even if we know that array would not be the expected one
return (array) $other;
}

private function isAssociative(array $array): bool
{
return \array_reduce(\array_keys($array), function (bool $carry, $key): bool {
return $carry || \is_string($key);
}, false);
}

private function compare($first, $second): bool
{
return $this->strict ? $first === $second : $first == $second;
}

private function deepSort(array &$array): void
{
foreach ($array as &$value) {
if (\is_array($value)) {
$this->deepSort($value);
}
}

if ($this->isAssociative($array)) {
\ksort($array);
} else {
\sort($array);
}
}

private function arrayIntersectRecursive(array $array, array $subset): array
{
$intersect = [];

if ($this->isAssociative($subset)) {
// If the subset is an associative array, get the intersection while
// preserving the keys.
foreach ($subset as $key => $subset_value) {
if (\array_key_exists($key, $array)) {
$array_value = $array[$key];

if (\is_array($subset_value) && \is_array($array_value)) {
$intersect[$key] = $this->arrayIntersectRecursive($array_value, $subset_value);
} elseif ($this->compare($subset_value, $array_value)) {
$intersect[$key] = $array_value;
}
}
}
} else {
// If the subset is an indexed array, loop over all entries in the
// haystack and check if they match the ones in the subset.
foreach ($array as $array_value) {
if (\is_array($array_value)) {
foreach ($subset as $key => $subset_value) {
if (\is_array($subset_value)) {
$recursed = $this->arrayIntersectRecursive($array_value, $subset_value);

if (!empty($recursed)) {
$intersect[$key] = $recursed;

break;
}
}
}
} else {
foreach ($subset as $key => $subset_value) {
if (!\is_array($subset_value) && $this->compare(
$subset_value,
$array_value
)) {
$intersect[$key] = $array_value;

break;
}
}
}
}
}

return $intersect;
}
}

0 comments on commit 84d01bb

Please sign in to comment.