From 067be1ab1d90cc6caf84b709db67692cd85d7cf1 Mon Sep 17 00:00:00 2001 From: Meritoo Date: Sat, 5 Feb 2022 19:50:36 +0100 Subject: [PATCH] [Arrays] Function that returns elements from given level --- CHANGELOG.md | 4 ++ src/Utilities/Arrays.php | 37 +++++++++++ tests/Utilities/ArraysTest.php | 110 +++++++++++++++++++++++++++++++++ 3 files changed, 151 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 82e49bd..f986f09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ Common and useful classes, methods, exceptions etc. +# 1.1.6 + +1. [Arrays] Function that returns elements from given level + # 1.1.5 1. [BaseCollection] Prepare elements while adding them by `addMultiple()` method in the same way as passing them in diff --git a/src/Utilities/Arrays.php b/src/Utilities/Arrays.php index 0a77a3f..3d6e302 100644 --- a/src/Utilities/Arrays.php +++ b/src/Utilities/Arrays.php @@ -1642,6 +1642,43 @@ class Arrays return '' === trim(implode('', $array)); } + public static function getElementsFromLevel(array $array, int $level): ?array + { + if (empty($array) || $level <= 0) { + return null; + } + + $result = []; + + foreach ($array as $value) { + // This is the expected level (the deepest). Comparing with 1, because level will be decreased by 1, and + // finally we will get the latest/deepest level that equals 1. + if ($level === 1) { + $result[] = $value; + continue; + } + + // There is no deeper level + if (!is_array($value)) { + continue; + } + + // Let's dive one level down + $elements = self::getElementsFromLevel($value, $level - 1); + + if ($elements === null) { + continue; + } + + // I have to load each element separately to avoid issue with incorrectly nested values + foreach ($elements as $element) { + $result[] = $element; + } + } + + return $result; + } + /** * Returns neighbour (next or previous element) for given element * diff --git a/tests/Utilities/ArraysTest.php b/tests/Utilities/ArraysTest.php index 385fc7a..377210c 100644 --- a/tests/Utilities/ArraysTest.php +++ b/tests/Utilities/ArraysTest.php @@ -1535,6 +1535,116 @@ letsTest[2] = value_2;'; static::assertSame($expected, Arrays::containsEmptyStringsOnly($array)); } + public function testGetElementsFromLevelIfArrayIsEmpty(): void + { + self::assertNull(Arrays::getElementsFromLevel([], -1)); + self::assertNull(Arrays::getElementsFromLevel([], 0)); + self::assertNull(Arrays::getElementsFromLevel([], 1)); + } + + public function testGetElementsFromLevelIfThereIsNoGivenLevel(): void + { + self::assertSame([], Arrays::getElementsFromLevel([1, 2, 3], 9999)); + } + + public function testGetElementsFromLevelIfGivenLevelIsNotPositiveValue(): void + { + self::assertNull(Arrays::getElementsFromLevel([1, 2, 3], -1)); + self::assertNull(Arrays::getElementsFromLevel([1, 2, 3], 0)); + } + + public function testGetElementsFromLevelIfArrayHasOneLevelOnly(): void + { + $array = [ + // Level 1: + 'ab', + 'cd', + 'ef', + ]; + + self::assertSame($array, Arrays::getElementsFromLevel($array, 1)); + } + + public function testGetElementsFromLevel(): void + { + $array = [ + // Level 1: + 'ab', + [ + // Level 2: + 'cd', + 'ef', + ], + + // Level 1: + [ + // Level 2: + 'gh', + [ + // Level 3: + 'ij', + 'kl', + ], + ], + + // Level 1: + [ + // Level 2: + [ + // Level 3: + 'mn', + 'op', + ], + ], + ]; + + $expectedLevel1 = [ + 'ab', + [ + 'cd', + 'ef', + ], + [ + 'gh', + [ + 'ij', + 'kl', + ], + ], + [ + [ + 'mn', + 'op', + ], + ], + ]; + + $expectedLevel2 = [ + 'cd', + 'ef', + 'gh', + [ + 'ij', + 'kl', + ], + [ + 'mn', + 'op', + ], + ]; + + $expectedLevel3 = [ + 'ij', + 'kl', + 'mn', + 'op', + ]; + + self::assertSame($expectedLevel1, Arrays::getElementsFromLevel($array, 1)); + self::assertSame($expectedLevel2, Arrays::getElementsFromLevel($array, 2)); + self::assertSame($expectedLevel3, Arrays::getElementsFromLevel($array, 3)); + } + /** * Provides simple array to set/replace values with keys *