public
Last active

next/previous sibling of an element in an associative array

  • Download Gist
ArraySiblingsTest.php
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

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.