Skip to content

Commit

Permalink
1
Browse files Browse the repository at this point in the history
  • Loading branch information
efrin committed Aug 10, 2014
1 parent 5f9c7a5 commit 74d2751
Show file tree
Hide file tree
Showing 3 changed files with 175 additions and 5 deletions.
45 changes: 40 additions & 5 deletions Ephrin/Structures/ArrayStructure.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ class ArrayStructure
* @return bool
* @throws \InvalidArgumentException
*/
public static function isSequential($value){
if(is_array($value) || ($value instanceof \Countable && $value instanceof \ArrayAccess)){
public static function isSequentialFastest($value)
{
if (is_array($value) || ($value instanceof \Countable && $value instanceof \ArrayAccess)) {
for ($i = count($value) - 1; $i >= 0; $i--) {
if (!isset($value[$i]) && !array_key_exists($i, $value)) {
return false;
Expand All @@ -28,23 +29,57 @@ public static function isSequential($value){
}
}

public static function isSequentialSimple(array $value)
{
return true !== boolval(array_diff_key($value, (new \SplFixedArray(count($value)))->toArray()));
}

/**
* @param array|\ArrayAccess|\Countable $value
* @return bool
* @throws \InvalidArgumentException
*/
public static function isSequentialExotic($value)
{
if (is_array($value) || ($value instanceof \Countable && $value instanceof \ArrayAccess)) {
$count = count($value);

$half = (int)floor($count / 2);

for ($m = 0; $m < $half; $m++) {
if (isset($value[$m]) && isset($value[$half + $m])) {
continue;
} elseif (!array_key_exists($m, $value) || !array_key_exists($half + $m, $value)) {
return false;
}
}

return !boolval($count % 2 && !isset($value[$count - 1]) && !array_key_exists($count - 1, $value));

} else {
throw new \InvalidArgumentException(
sprintf('Data type "%s" is not supported by method %s', gettype($value), __METHOD__)
);
}
}

/**
* Reverse to \Ephrin\Structures\ArrayStructure::isSequential
* @param $value
* @return bool
*/
public static function isHash($value)
{
return !self::isSequential($value);
return !self::isSequentialFastest($value);
}

/**
* Another one
* Another one
* @param $value
* @return bool
*/
public static function isAssoc($value)
{
return array_keys($value) !== range(0, count($value) - 1);
}
}
}
116 changes: 116 additions & 0 deletions Ephrin/Structures/Tests/StructureTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<?php


namespace Ephrin\Structures\Tests;



use Ephrin\Structures\ArrayStructure;

class StructureTest extends \PHPUnit_Framework_TestCase
{



public function testArrayKeysConvertsToIntegers(){
$a = [];

$key = (string)1;

$this->assertTrue(is_string($key));

$a[$key] = $key;

$this->assertFalse(is_string(array_pop(array_keys($a))));

}




public function testArrays()
{
$total = 1000000;


$try1 = array_fill(0, $total, 1);
$try1[rand(0, count($try1)-1)] = null;

$try2 = array_fill(0, $total, 1);
$try2[rand(0, count($try1)-1)] = null;
$try2[(string)count($try2)] = 'value';

$uk = rand(0, $total);
unset($try2[$uk]);

print 'isSequentialFastest:'.PHP_EOL;

\PHP_Timer::start();
$isHashFalse = !ArrayStructure::isSequentialFastest($try1);
$time = \PHP_Timer::stop();
print \PHP_Timer::secondsToTimeString($time) . PHP_EOL;

\PHP_Timer::start();
$isHashTrue = !ArrayStructure::isSequentialFastest($try2);
$time = \PHP_Timer::stop();
print \PHP_Timer::secondsToTimeString($time) . PHP_EOL;

$this->assertFalse($isHashFalse);
$this->assertTrue($isHashTrue);


print 'isSequentialSimple:'.PHP_EOL;

\PHP_Timer::start();
$isSeqFalse = !ArrayStructure::isSequentialSimple($try1);
$time = \PHP_Timer::stop();
print \PHP_Timer::secondsToTimeString($time) . PHP_EOL;

\PHP_Timer::start();
$isSeqTrue = !ArrayStructure::isSequentialSimple($try2);
$time = \PHP_Timer::stop();
print \PHP_Timer::secondsToTimeString($time) . PHP_EOL;

$this->assertFalse($isSeqFalse);
$this->assertTrue($isSeqTrue);

print 'isSequentialExotic:'.PHP_EOL;

\PHP_Timer::start();
$isSeqTrue = ArrayStructure::isSequentialExotic($try1);
$time = \PHP_Timer::stop();
print \PHP_Timer::secondsToTimeString($time) . PHP_EOL;

\PHP_Timer::start();
$isSeqFalse = ArrayStructure::isSequentialExotic($try2);
$time = \PHP_Timer::stop();
print \PHP_Timer::secondsToTimeString($time) . PHP_EOL;

$this->assertFalse($isSeqFalse);
$this->assertTrue($isSeqTrue);


print 'isAssoc:'.PHP_EOL;

\PHP_Timer::start();
$isAssocFalse = ArrayStructure::isAssoc($try1);
$time = \PHP_Timer::stop();
print \PHP_Timer::secondsToTimeString($time) . PHP_EOL;

\PHP_Timer::start();
$isAssocTrue = ArrayStructure::isAssoc($try2);
$time = \PHP_Timer::stop();
print \PHP_Timer::secondsToTimeString($time) . PHP_EOL;

$this->assertFalse($isAssocFalse);
$this->assertTrue($isAssocTrue);





}



}
19 changes: 19 additions & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>

<phpunit backupGlobals="false"
backupStaticAttributes="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
bootstrap="./vendor/autoload.php">
<testsuites>
<testsuite name="Ephrin Structures Test Suite">
<directory>./Ephrin/Structures</directory>
</testsuite>
</testsuites>

</phpunit>

0 comments on commit 74d2751

Please sign in to comment.