Skip to content

Commit

Permalink
allow object as key
Browse files Browse the repository at this point in the history
  • Loading branch information
sokil committed Jul 14, 2016
1 parent 0f43ea7 commit 98ea5c6
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 52 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
vendor
.idea
nbproject
nbproject
composer.lock
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,17 @@ 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:

```php
<?php

$list = new \Sokil\DataType\PriorityList();
$list = new \Sokil\DataType\PriorityMap();
$list->set('key1', 'value1', 10);
$list->set('key2', 'value2', 100);
```
Expand All @@ -54,7 +54,7 @@ Get element by key:
```php
<?php

$list = new \Sokil\DataType\PriorityList();
$list = new \Sokil\DataType\PriorityMap();
$list->set('key1', 'value1', 10);
$list->get('key1');
```
Expand Down
101 changes: 95 additions & 6 deletions src/PriorityList.php → src/PriorityMap.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Sokil\DataType;

class PriorityList implements \Iterator, \Countable
class PriorityMap implements \Iterator, \Countable
{
private $lastSequence = 0;

Expand All @@ -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;
Expand All @@ -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) {
Expand All @@ -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) {
Expand All @@ -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);
Expand Down
67 changes: 26 additions & 41 deletions tests/PriorityListTest.php → tests/PriorityMapTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -38,7 +36,7 @@ public function testToArrayDesc()

public function testToArrayAsc()
{
$list = new PriorityList();
$list = new PriorityMap();

$list->setAscOrder();

Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -96,30 +94,20 @@ public function testGetKeys()
$list->getKeys()
);
}

public function testGetKeys_EmptyList()
{
$list = new PriorityList();
$list = new PriorityMap();

$this->assertEquals(
array(),
$list->getKeys()
);
}

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);
Expand All @@ -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());
}
}

0 comments on commit 98ea5c6

Please sign in to comment.