Skip to content
Create a gist now

Instantly share code, notes, and snippets.

next/previous sibling of an element in an associative array
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:


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.