Skip to content

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
next/previous sibling of an element in an associative array
<?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));
}
}
@ggalmazor

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

@gonzalo123
Owner

gist actualizado

@ggalmazor

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.