A simple array data structure implementation in PHP, version 1
In this version of array data structure implementation in PHP, we use the simple approach without using any more advanced PHP features (like iterators). Because of the step-by-step attitude of these articles (the next versions, I mean), We try to use some compatible codes along with all versions.
The final desired result is a class called IntOneDimArray
(as well as FloatOneDimArray
and etc.) that used by initialization statement $intArray = new IntOneDimArray($size);
, and later used by setter and getters like this:
echo $intArray->Set($i, $v)
echo $intArray->Get($i)
At the first, we create a simple abstract class called AbstractOneDimArray
.
The very first thing we learn about simple arrays is that there is a limitation for the number of items. (changeable in case of the dynamic array and fixed in case of fixed or static arrays) We tend to implement a simple array, and by simple we mean fixed size as well.
protected $_size = 0;
We use the native PHP array as a data holder for own data structure. (As it seems rediculous, but we focus on teaching purposes)
protected $_values = [];
To acess the array size, we implement a Size
method.
public function Size() : int
{
return $this->_size;
}
Until now, the implemented class seems like this:
abstract class AbstractOneDimArray
{
protected $_size = 0;
protected $_values = [];
public function __construct(int $size)
{
if ($size < 0)
throw new \Exception('Size must be positive number.');
$this->_size = $size;
}
public function Size() : int
{
return $this->_size;
}
}
For the reason that out abstract class must be a parent class for concrete classes, and each concrete class has it's own data type, we declare an abstract method called getValueType
to be implemented in each concrete class.
protected abstract function getValueType() : string;
Also, we declare another abstract method to return default value for the specified data type.
protected abstract function getDefaultValue();
We use this methods in the constructor like this:
public function __construct(int $size)
{
if ($size < 0)
throw new Exception('Size must be positive number.');
$this->_size = $size;
$defaultValue = $this->getDefaultValue();
if (gettype($defaultValue) != $this->getValueType())
throw new Exception('Return type of the getDefaultValue() does not match getValueType().');
for ($i = 0; $i _size; $i++)
$this->_values[$i] = $defaultValue;
}
Of course, it must contain getter and setter methods to be an array data structure parent class! The implementation is like this:
public function Set(int $index, $value)
{
if ($index < 0 || $index >= $this->_size)
throw new Exception('The index must be in the range (0, ' . ($this->_size -1) . ')');
if (gettype($value) != $this->getValueType())
throw new Exception('The value must be of type ' . $this->getValueType());
$this->_values[$index] = $value;
}
public function Get(int $index)
{
if ($index < 0 || $index >= $this->_size)
throw new Exception('The index must be in the range (0, ' . ($this->_size -1) . ')');
return $this->_values[$index];
}
The base class is finished now and it's like this:
abstract class AbstractOneDimArray
{
/**
*
* @var int
*/
protected /*int*/ $_size = 0;
/**
*
* @var array
*/
protected /*array*/ $_values = [];
protected abstract function getValueType() : string;
protected abstract function getDefaultValue();
public function __construct(int $size)
{
if ($size < 0)
throw new Exception('Size must be positive number.');
$this->_size = $size;
$defaultValue = $this->getDefaultValue();
if (gettype($defaultValue) != $this->getValueType())
throw new Exception('Return type of the getDefaultValue() does not match getValueType().');
for ($i = 0; $i < $this->_size; $i++)
$this->_values[$i] = $defaultValue;
}
public function Size() : int
{
return $this->_size;
}
public function Set(int $index, $value)
{
if ($index < 0 || $index >= $this->_size)
throw new Exception('The index must be in the range (0, ' . ($this->_size -1) . ')');
if (gettype($value) != $this->getValueType())
throw new Exception('The value must be of type ' . $this->getValueType());
$this->_values[$index] = $value;
}
public function Get(int $index)
{
if ($index < 0 || $index >= $this->_size)
throw new Exception('The index must be in the range (0, ' . ($this->_size -1) . ')');
return $this->_values[$index];
}
}
Now to use this base class, we need to derive a concrete class. For example we make the class IntOneDimArray
to use as an integral array.
class IntOneDimArray extends AbstractOneDimArray
{
protected function getValueType() : string
{
return gettype(0);
}
protected function getDefaultValue()
{
return 0;
}
}
As you see, We only need to implement the two methods getValueType
and getDefaultValue
. The other operations is derived from the base class. Lets test implemented code with an execution.
$size = 5;
$intArray = new IntOneDimArray($size);
for ($i = 0; $i Size(); $i++) {
echo $intArray->Get($i) . ', ';
}
echo PHP_EOL;
for ($i = 0; $i Size(); $i++) {
$intArray->Set($i, $i);
}
for ($i = 0; $i Size(); $i++) {
echo $intArray->Get($i) . ', ';
}
echo PHP_EOL;
echo $intArray->Get($size);
The output will be like this:
0, 0, 0, 0, 0 0, 1, 2, 3, 4 5
Code
<?php
namespace Techanic\CS\DS\Linear\Vector;
use Exception;
abstract class AbstractOneDimArray
{
/**
*
* @var int
*/
protected /*int*/ $_size = 0;
/**
*
* @var array
*/
protected /*array*/ $_values = [];
protected abstract function getValueType() : string;
protected abstract function getDefaultValue();
public function __construct(int $size)
{
if ($size < 0)
throw new Exception('Size must be positive number.');
$this->_size = $size;
$defaultValue = $this->getDefaultValue();
if (gettype($defaultValue) != $this->getValueType())
throw new Exception('Return type of the getDefaultValue() does not match getValueType().');
for ($i = 0; $i < $this->_size; $i++)
$this->_values[$i] = $defaultValue;
}
public function Size() : int
{
return $this->_size;
}
public function Set(int $index, $value)
{
if ($index < 0 || $index >= $this->_size)
throw new Exception('The index must be in the range (0, ' . ($this->_size -1) . ')');
if (gettype($value) != $this->getValueType())
throw new Exception('The value must be of type ' . $this->getValueType());
$this->_values[$index] = $value;
}
public function Get(int $index)
{
if ($index < 0 || $index >= $this->_size)
throw new Exception('The index must be in the range (0, ' . ($this->_size -1) . ')');
return $this->_values[$index];
}
}
class IntOneDimArray extends AbstractOneDimArray
{
protected function getValueType() : string
{
return gettype(0);
}
protected function getDefaultValue()
{
return 0;
}
}
$size = 5;
$intArray = new IntOneDimArray($size);
for ($i = 0; $i < $intArray->Size(); $i++) {
echo $intArray->Get($i) . ', ';
}
echo PHP_EOL;
for ($i = 0; $i < $intArray->Size(); $i++) {
$intArray->Set($i, $i);
}
for ($i = 0; $i < $intArray->Size(); $i++) {
echo $intArray->Get($i) . ', ';
}
echo PHP_EOL;
echo $intArray->Get($size);