Created

Embed URL

HTTPS clone URL

SSH clone URL

You can clone with HTTPS or SSH.

Download Gist

next/previous sibling of an element in an associative array

View ArraySiblingsTest.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
<?php
interface ArraySiblingsInterface
{
public static function previous($needle, $haystack, $continueAtTop = true);
public static function next($needle, $haystack, $continueAtBottom = true);
}
class ArraySiblings implements ArraySiblingsInterface
{
const FORWARD = 'fwd';
const BACKWARDS = 'bwd';
static private function _walk($needle, $haystack, $continue, $direction)
{
if ($direction == self::BACKWARDS) {
$haystack = array_reverse($haystack, true);
}
$keys = array_keys($haystack);
if ($continue) $keys = array_merge($keys, $keys);
$pos = array_keys($keys, $needle);
if (! isset($pos[0])) return;
$pos = $pos[0];
$next = $pos+1;
if (!isset($keys[$next])) return null;
return $haystack[$keys[$next]];
}
static function next($needle, $haystack, $continueAtBottom = true)
{
return self::_walk($needle, $haystack, $continueAtBottom, self::FORWARD);
}
static function previous($needle, $haystack, $continueAtTop = true)
{
return self::_walk($needle, $haystack, $continueAtTop, self::BACKWARDS);
}
}
class ArraySiblingsTest extends PHPUnit_Framework_TestCase {
protected $coll = array(
'lalala' => 1,
'pepepe' => 2,
'cocotero' => 3,
'periquito' => 4
);
public function testShouldReturnNullIfTheNeedleDoesNotExistInHaystack() {
$this->assertEquals(null, ArraySiblings::next('chuchu', $this->coll));
}
public function testShouldTheNeedleElementIfOnlyOneElementInHaystack() {
$this->assertEquals('blabla', ArraySiblings::next('chuchu', array('chuchu' => 'blabla')));
}
public function testShouldReturnNextSibling() {
$this->assertEquals(3, ArraySiblings::next('pepepe', $this->coll));
}
public function testShouldReturnPreviousSibling() {
$this->assertEquals(2, ArraySiblings::previous('cocotero', $this->coll));
}
public function testShouldGoBeyondBoundsAtTop() {
$this->assertEquals(1, ArraySiblings::next('periquito', $this->coll));
}
public function testShouldGoBeyondBoundsAtBottom() {
$this->assertEquals(4, ArraySiblings::previous('lalala', $this->coll));
}
public function testShouldReturnNullIfOnlyOneElementInArrayAndToldNotToContinueAtBounds() {
$this->assertEquals(null, ArraySiblings::next('chuchu', array('chuchu' => 'blabla'), false));
$this->assertEquals(null, ArraySiblings::previous('chuchu', array('chuchu' => 'blabla'), false));
}
public function testShouldReturnNullIfToldNotToContinueAtTop() {
$this->assertEquals(null, ArraySiblings::next('periquito', $this->coll, false));
}
public function testShouldReturnNullIfToldNotToContinueAtBottom() {
$this->assertEquals(null, ArraySiblings::previous('lalala', $this->coll, false));
}
}

Gracias Gonzalo!

Si te apetece intenta adaptar la clase al interfaz que defino. He actualizado mi Gist aƱadiendo los tests: https://gist.github.com/882894

Owner

gist actualizado

Genial! Thx!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.