From 98ea5c620749ca46c82b9f631149e84256e082be Mon Sep 17 00:00:00 2001 From: Dmytro Sokil Date: Thu, 14 Jul 2016 23:02:40 +0300 Subject: [PATCH] allow object as key --- .gitignore | 3 +- README.md | 8 +- src/{PriorityList.php => PriorityMap.php} | 101 ++++++++++++++++-- ...iorityListTest.php => PriorityMapTest.php} | 67 +++++------- 4 files changed, 127 insertions(+), 52 deletions(-) rename src/{PriorityList.php => PriorityMap.php} (56%) rename tests/{PriorityListTest.php => PriorityMapTest.php} (70%) diff --git a/.gitignore b/.gitignore index cc46f4e..f6d160e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ vendor .idea -nbproject \ No newline at end of file +nbproject +composer.lock \ No newline at end of file diff --git a/README.md b/README.md index c83b113..318b4e3 100644 --- a/README.md +++ b/README.md @@ -21,9 +21,9 @@ You can install library through Composer: } ``` -## Priority List +## Priority Map -Priority list allows you to specify priority of items and +Priority map allows you to specify priority of items and iterate through this list in order to priority. Add elements to list with priority: @@ -31,7 +31,7 @@ Add elements to list with priority: ```php set('key1', 'value1', 10); $list->set('key2', 'value2', 100); ``` @@ -54,7 +54,7 @@ Get element by key: ```php set('key1', 'value1', 10); $list->get('key1'); ``` diff --git a/src/PriorityList.php b/src/PriorityMap.php similarity index 56% rename from src/PriorityList.php rename to src/PriorityMap.php index 87ff11a..dc6bb62 100644 --- a/src/PriorityList.php +++ b/src/PriorityMap.php @@ -2,7 +2,7 @@ namespace Sokil\DataType; -class PriorityList implements \Iterator, \Countable +class PriorityMap implements \Iterator, \Countable { private $lastSequence = 0; @@ -14,14 +14,29 @@ class PriorityList implements \Iterator, \Countable private $order = self::ORDER_DESC; /** + * Get scalar key from mixed + */ + private function getScalarKey($key) + { + if (is_object($key)) { + return spl_object_hash($key); + } else { + return $key; + } + } + + /** + * Add new item to map * * @param string $key name * @param string $value value * @param string $priority priority - * @return \Sokil\PriorityList + * @return PriorityMap */ public function set($key, $value, $priority = 0) { + $key = $this->getScalarKey($key); + $this->list[$key] = new \stdclass(); $this->list[$key]->value = $value; $this->list[$key]->priority = (int) $priority; @@ -30,38 +45,79 @@ public function set($key, $value, $priority = 0) return $this->list[$key]; } - public function get($name) + /** + * Get item from map + * + * @param $key + * @return null + */ + public function get($key) { - return isset($this->list[$name]) ? $this->list[$name]->value : null; + $key = $this->getScalarKey($key); + return isset($this->list[$key]) ? $this->list[$key]->value : null; } - public function has($name) + /** + * Check if item in map + * + * @param $key + * @return bool + */ + public function has($key) { - return isset($this->list[$name]); + $key = $this->getScalarKey($key); + return isset($this->list[$key]); } + /** + * Get list of keys + * + * @return array + */ public function getKeys() { return array_keys($this->list); } + /** + * Get count or map + * + * @return int + */ public function count() { return count($this->list); } + /** + * Set ASC direction of sorting + * + * @return $this + */ public function setAscOrder() { $this->order = self::ORDER_ASC; return $this; } + /** + * Set DESC direction of sorting + * + * @return $this + */ public function setDescOrder() { $this->order = self::ORDER_DESC; return $this; } + /** + * ASC sort strategy + * + * @param $declaration1 + * @param $declaration2 + * @return int + */ private function ascSortStrategy($declaration1, $declaration2) { if($declaration1->priority === $declaration2->priority) { @@ -71,6 +127,13 @@ private function ascSortStrategy($declaration1, $declaration2) return $declaration1->priority > $declaration2->priority ? 1 : -1; } + /** + * DESC sort strategy + * + * @param $declaration1 + * @param $declaration2 + * @return int + */ private function descSortStrategy($declaration1, $declaration2) { if($declaration1->priority === $declaration2->priority) { @@ -80,33 +143,59 @@ private function descSortStrategy($declaration1, $declaration2) return $declaration1->priority < $declaration2->priority ? 1 : -1; } + /** + * Reset iterator + */ public function rewind() { uasort($this->list, array($this, $this->order . 'SortStrategy')); reset($this->list); } + /** + * Get current item + * + * @return mixed + */ public function current() { $item = current($this->list); return $item->value; } + /** + * Get current key + * + * @return mixed + */ public function key() { return key($this->list); } + /** + * Mve iterator next + */ public function next() { next($this->list); } + /** + * Check if current key is valid + * + * @return bool + */ public function valid() { return null !== $this->key(); } + /** + * Convert map to array + * + * @return array + */ public function toArray() { return iterator_to_array($this); diff --git a/tests/PriorityListTest.php b/tests/PriorityMapTest.php similarity index 70% rename from tests/PriorityListTest.php rename to tests/PriorityMapTest.php index 454714b..0009114 100644 --- a/tests/PriorityListTest.php +++ b/tests/PriorityMapTest.php @@ -2,13 +2,11 @@ namespace Sokil\DataType; -class PriorityListTest extends \PHPUnit_Framework_TestCase +class PriorityMapTest extends \PHPUnit_Framework_TestCase { public function testToArrayDesc() { - $list = new PriorityList(); - - $this->assertEquals(array('a' => 'a', 'b' => 'b'), array('b' => 'b', 'a' => 'a')); + $list = new PriorityMap(); $list->set('k1', 'v1', 2); $list->set('k2', 'v2', 8); @@ -38,7 +36,7 @@ public function testToArrayDesc() public function testToArrayAsc() { - $list = new PriorityList(); + $list = new PriorityMap(); $list->setAscOrder(); @@ -70,7 +68,7 @@ public function testToArrayAsc() public function testGet() { - $list = new PriorityList(); + $list = new PriorityMap(); $list->set('k1', 'v1', 2); $list->set('k2', 'v2', 8); @@ -83,7 +81,7 @@ public function testGet() public function testGetKeys() { - $list = new PriorityList(); + $list = new PriorityMap(); $list->set('k1', 'v1', 2); $list->set('k2', 'v2', 8); @@ -96,10 +94,10 @@ public function testGetKeys() $list->getKeys() ); } - + public function testGetKeys_EmptyList() { - $list = new PriorityList(); + $list = new PriorityMap(); $this->assertEquals( array(), @@ -107,19 +105,9 @@ public function testGetKeys_EmptyList() ); } - public function testHas() - { - $list = new PriorityList(); - - $list->set('k1', 'v1', 2); - - $this->assertTrue($list->has('k1')); - $this->assertFalse($list->has('UNKNOWN_KEY')); - } - public function testGet_KeyNotExists() { - $list = new PriorityList(); + $list = new PriorityMap(); $list->set('k1', 'v1', 2); $list->set('k2', 'v2', 8); @@ -130,33 +118,30 @@ public function testGet_KeyNotExists() $this->assertEquals(null, $list->get('KEY_NOT_EXISTS')); } - public function testToArray() + public function testHas() { - $list = new PriorityList(); + $list = new PriorityMap(); $list->set('k1', 'v1', 2); - $list->set('k2', 'v2', 8); - $list->set('k3', 'v3', 16); - $list->set('k4', 'v4', 1); - $list->set('k5', 'v5', 4); - $expectedArray = array( - 'k3' => 'v3', - 'k2' => 'v2', - 'k5' => 'v5', - 'k1' => 'v1', - 'k4' => 'v4', - ); + $this->assertTrue($list->has('k1')); + $this->assertFalse($list->has('UNKNOWN_KEY')); + } - foreach($list->toArray() as $key => $value) { - $this->assertEquals(key($expectedArray), $key); - $this->assertEquals(current($expectedArray), $value); + public function testSet_ObjectKey() + { + $key1 = new \stdClass(); + $key2 = new \stdClass(); + $key3 = new \stdClass(); - next($expectedArray); - } + $list = new PriorityMap(); + $list->setAscOrder(); - if(key($expectedArray)) { - $this->fail('Actual list less than expected'); - } + $list->set($key1, 42, 1); + $list->set($key2, 41, 0); + $list->set($key3, 43, 2); + + $list->rewind(); + $this->assertEquals(41, $list->current()); } }