Skip to content

Commit 56fbe10

Browse files
author
nejc
committed
feat: add array types and abstractions
1 parent d4c266d commit 56fbe10

File tree

6 files changed

+291
-167
lines changed

6 files changed

+291
-167
lines changed

examples/array_operations.php

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
<?php
2+
3+
require_once __DIR__ . '/../vendor/autoload.php';
4+
5+
use Nejcc\PhpDatatypes\Scalar\Integers\Signed\Int8;
6+
use Nejcc\PhpDatatypes\Scalar\FloatingPoints\Float32;
7+
8+
/**
9+
* Example 1: Working with Arrays of Int8
10+
*/
11+
echo "Example 1: Working with Arrays of Int8\n";
12+
echo "==================================\n";
13+
14+
try {
15+
// Create an array of Int8 values
16+
$numbers = [
17+
new Int8(10),
18+
new Int8(20),
19+
new Int8(30),
20+
new Int8(40),
21+
new Int8(50)
22+
];
23+
24+
// Sum all numbers
25+
$sum = new Int8(0);
26+
foreach ($numbers as $number) {
27+
$sum = $sum->add($number);
28+
}
29+
30+
echo "Sum of numbers: " . $sum->getValue() . "\n";
31+
32+
// Find maximum value
33+
$max = $numbers[0];
34+
foreach ($numbers as $number) {
35+
if ($number->greaterThan($max)) {
36+
$max = $number;
37+
}
38+
}
39+
40+
echo "Maximum value: " . $max->getValue() . "\n";
41+
} catch (\Exception $e) {
42+
echo "Error: " . $e->getMessage() . "\n";
43+
}
44+
45+
/**
46+
* Example 2: Array Operations with Float32
47+
*/
48+
echo "\nExample 2: Array Operations with Float32\n";
49+
echo "====================================\n";
50+
51+
try {
52+
// Create an array of Float32 values
53+
$temperatures = [
54+
new Float32(23.5),
55+
new Float32(24.8),
56+
new Float32(22.3),
57+
new Float32(25.1),
58+
new Float32(23.9)
59+
];
60+
61+
// Calculate average temperature
62+
$sum = new Float32(0.0);
63+
foreach ($temperatures as $temp) {
64+
$sum = $sum->add($temp);
65+
}
66+
$average = $sum->divide(new Float32(count($temperatures)));
67+
68+
echo "Average temperature: " . $average->getValue() . "°C\n";
69+
70+
// Find temperatures above average
71+
echo "Temperatures above average:\n";
72+
foreach ($temperatures as $temp) {
73+
if ($temp->greaterThan($average)) {
74+
echo "- " . $temp->getValue() . "°C\n";
75+
}
76+
}
77+
} catch (\Exception $e) {
78+
echo "Error: " . $e->getMessage() . "\n";
79+
}
80+
81+
/**
82+
* Example 3: Mixed Type Arrays
83+
*/
84+
echo "\nExample 3: Mixed Type Arrays\n";
85+
echo "=========================\n";
86+
87+
try {
88+
// Create arrays of different types
89+
$integers = [
90+
new Int8(1),
91+
new Int8(2),
92+
new Int8(3)
93+
];
94+
95+
$floats = [
96+
new Float32(1.5),
97+
new Float32(2.5),
98+
new Float32(3.5)
99+
];
100+
101+
// Convert integers to floats
102+
$convertedFloats = array_map(
103+
fn(Int8 $int) => new Float32($int->getValue()),
104+
$integers
105+
);
106+
107+
echo "Original integers: " . implode(', ', array_map(fn(Int8 $int) => $int->getValue(), $integers)) . "\n";
108+
echo "Converted to floats: " . implode(', ', array_map(fn(Float32 $float) => $float->getValue(), $convertedFloats)) . "\n";
109+
110+
// Add corresponding values
111+
$sums = [];
112+
for ($i = 0; $i < count($integers); $i++) {
113+
$sums[] = $floats[$i]->add(new Float32($integers[$i]->getValue()));
114+
}
115+
116+
echo "Sums of corresponding values: " . implode(', ', array_map(fn(Float32 $float) => $float->getValue(), $sums)) . "\n";
117+
} catch (\Exception $e) {
118+
echo "Error: " . $e->getMessage() . "\n";
119+
}
120+
121+
/**
122+
* Example 4: Array Filtering and Mapping
123+
*/
124+
echo "\nExample 4: Array Filtering and Mapping\n";
125+
echo "==================================\n";
126+
127+
try {
128+
// Create an array of Int8 values
129+
$numbers = [
130+
new Int8(-5),
131+
new Int8(0),
132+
new Int8(5),
133+
new Int8(10),
134+
new Int8(15),
135+
new Int8(20)
136+
];
137+
138+
// Filter positive numbers
139+
$positiveNumbers = array_filter(
140+
$numbers,
141+
fn(Int8 $num) => $num->greaterThan(new Int8(0))
142+
);
143+
144+
echo "Positive numbers: " . implode(', ', array_map(fn(Int8 $num) => $num->getValue(), $positiveNumbers)) . "\n";
145+
146+
// Double each number
147+
$doubledNumbers = array_map(
148+
fn(Int8 $num) => $num->multiply(new Int8(2)),
149+
$numbers
150+
);
151+
152+
echo "Doubled numbers: " . implode(', ', array_map(fn(Int8 $num) => $num->getValue(), $doubledNumbers)) . "\n";
153+
} catch (\Exception $e) {
154+
echo "Error: " . $e->getMessage() . "\n";
155+
}
156+
157+
/**
158+
* Example 5: Array Reduction
159+
*/
160+
echo "\nExample 5: Array Reduction\n";
161+
echo "========================\n";
162+
163+
try {
164+
// Create an array of Float32 values
165+
$values = [
166+
new Float32(1.5),
167+
new Float32(2.5),
168+
new Float32(3.5),
169+
new Float32(4.5)
170+
];
171+
172+
// Calculate product of all values
173+
$product = array_reduce(
174+
$values,
175+
fn(Float32 $carry, Float32 $item) => $carry->multiply($item),
176+
new Float32(1.0)
177+
);
178+
179+
echo "Product of all values: " . $product->getValue() . "\n";
180+
181+
// Calculate sum of squares
182+
$sumOfSquares = array_reduce(
183+
$values,
184+
fn(Float32 $carry, Float32 $item) => $carry->add($item->multiply($item)),
185+
new Float32(0.0)
186+
);
187+
188+
echo "Sum of squares: " . $sumOfSquares->getValue() . "\n";
189+
} catch (\Exception $e) {
190+
echo "Error: " . $e->getMessage() . "\n";
191+
}

src/Abstract/ArrayAbstraction.php

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?php
2+
3+
namespace Nejcc\PhpDatatypes\Abstract;
4+
5+
abstract class ArrayAbstraction implements \Countable, \IteratorAggregate {
6+
protected array $value;
7+
8+
public function __construct(array $value) {
9+
$this->value = $value;
10+
}
11+
12+
public function getValue(): array {
13+
return $this->value;
14+
}
15+
16+
public function count(): int {
17+
return count($this->value);
18+
}
19+
20+
public function getIterator(): \ArrayIterator {
21+
return new \ArrayIterator($this->value);
22+
}
23+
24+
public function toArray(): array {
25+
return $this->value;
26+
}
27+
28+
// Add this for use by FloatArray and similar subclasses
29+
protected function validateFloats(array $array): void
30+
{
31+
foreach ($array as $item) {
32+
if (!is_float($item)) {
33+
throw new \Nejcc\PhpDatatypes\Exceptions\InvalidFloatException("All elements must be floats. Invalid value: " . json_encode($item));
34+
}
35+
}
36+
}
37+
38+
protected function validateStrings(array $array): void
39+
{
40+
foreach ($array as $item) {
41+
if (!is_string($item)) {
42+
throw new \Nejcc\PhpDatatypes\Exceptions\InvalidStringException("All elements must be strings. Invalid value: " . json_encode($item));
43+
}
44+
}
45+
}
46+
47+
protected function validateBytes(array $array): void
48+
{
49+
foreach ($array as $item) {
50+
if (!is_int($item) || $item < 0 || $item > 255) {
51+
throw new \Nejcc\PhpDatatypes\Exceptions\InvalidByteException("All elements must be valid bytes (0-255). Invalid value: " . $item);
52+
}
53+
}
54+
}
55+
56+
protected function validateJson(string $json): void
57+
{
58+
try {
59+
json_decode($json, true, 512, JSON_THROW_ON_ERROR);
60+
} catch (\JsonException $e) {
61+
throw new \InvalidArgumentException('Invalid JSON provided: ' . $e->getMessage());
62+
}
63+
}
64+
65+
}

src/Composite/Arrays/ByteSlice.php

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@
88
use IteratorAggregate;
99
use Traversable;
1010
use Nejcc\PhpDatatypes\Exceptions\InvalidByteException;
11+
use Nejcc\PhpDatatypes\Abstract\ArrayAbstraction;
1112

12-
readonly class ByteSlice implements Countable, ArrayAccess, IteratorAggregate
13+
class ByteSlice extends ArrayAbstraction implements ArrayAccess, Countable, IteratorAggregate
1314
{
1415
/**
1516
* @var array<int> The byte values (0-255).
1617
*/
17-
private array $value;
18+
protected array $value;
1819

1920
/**
2021
* Constructor for ByteSlice.
@@ -28,22 +29,6 @@ public function __construct(array $value)
2829
$this->value = $value;
2930
}
3031

31-
/**
32-
* Validate that all elements are valid bytes (0-255).
33-
*
34-
* @param array $array The array to validate.
35-
* @throws InvalidByteException If any element is not a valid byte.
36-
* @return void
37-
*/
38-
private function validateBytes(array $array): void
39-
{
40-
foreach ($array as $item) {
41-
if (!is_int($item) || $item < 0 || $item > 255) {
42-
throw new InvalidByteException("All elements must be valid bytes (0-255). Invalid value: " . $item);
43-
}
44-
}
45-
}
46-
4732
/**
4833
* Get the array of byte values.
4934
*
@@ -158,9 +143,9 @@ public function offsetUnset(mixed $offset): void
158143
/**
159144
* Get an iterator for the byte array.
160145
*
161-
* @return Traversable An iterator for the byte array.
146+
* @return \ArrayIterator An iterator for the byte array.
162147
*/
163-
public function getIterator(): Traversable
148+
public function getIterator(): \ArrayIterator
164149
{
165150
return new \ArrayIterator($this->value);
166151
}

0 commit comments

Comments
 (0)