Preface
Goal: Learning PHP without HTML burden. Continue Part Two
7: Approach in Solving Unique
A custom example, that you can rewrite.
An Algorithm Case
Why reinvent the wheel?
My intention is writing a custom pattern matching example, so later I can rewrite other algorithm based on this example. You can read the detail on the first article. The record overview.
Consider going back to simple data. We need to discuss about solving unique list.
x:xs Pattern Matching
The original x:xs
pattern matching is made of two functions:
- Exclude
- Unique
Pattern matching in PHP
,
is not as fancy as haskell
, or even OCaml
.
But what we have in PHP
is enough,
to solve our little problem.
Exclude Function
The exclude
function is just a filter
with below details:
<?php
$tags = ['60s', 'jazz', '60s', 'rock',
'70s', 'rock', '70s', 'pop'];
function exclude($val, $tags) {
return array_values(
array_filter(
$tags,
function ($tag) use ($val) {
return $tag != $val;
}));
}
$tags = exclude('rock', $tags);
printf("%s\n", json_encode($tags));
With the result as below array
:
❯ php 21-exclude.php
["60s","jazz","60s","70s","70s","pop"]
Exclude Using Array Difference
PHP can remove array by using array_diff
function,
to make our life simpler.
<?php
function exclude($val, $tags) {
return array_values(
array_diff($tags, [$val]));
}
Recursive Unique Function
With exclude
function above,
we can build unique
function recursively, as below code:
<?php
function unique($tags) {
if(sizeof($tags) <= 1) return $tags;
else {
$head = array_shift($tags);
return array_merge(
[$head],
unique(exclude($head, $tags))
);
}
}
printf("%s\n", json_encode(unique($tags)));
With the result as below array
:
❯ php 22-unique-a.py
['60s', 'jazz', 'rock', '70s', 'pop']
Now we can apply the method to our unique song challenge.
<?php
require_once(__DIR__.'/MyClassSongs.php');
function exclude($val, $tags) { .... }
function unique($tags) { .... }
$tagss = array_map(
function ($song) { return $song->tags; },
$songs);
$tags = array_merge(...$tagss);
$tags = unique($tags);
printf("%s\n", json_encode($tags));
- With the same result as below
❯ php 22-unique-b.php
["60s","jazz","rock","70s","pop"]
A Simpler Unique
With PHP
s array_diff
function,
the function is even simpler.
We can also put this into its own helper module.
<?php
function unique($tags) {
if(sizeof($tags) <= 1) return $tags;
else {
$head = array_shift($tags);
$exclude = array_values(
array_diff($tags, [$head]));
return array_merge(
[$head], unique($exclude)
);
}
}
Now we can apply to out test array.
<?php
require_once(__DIR__.'/MyHelperUnique.php');
$tags = ['60s', 'jazz', '60s', 'rock',
'70s', 'rock', '70s', 'pop'];
printf("%s\n", json_encode(unique($tags)));
Applying Unique to data Structure
We can also apply the method to our unique song challenge.
<?php
require_once(__DIR__.'/MyClassSongs.php');
require_once(__DIR__.'/MyHelperUnique.php');
$tagss = array_map(
function ($song) { return $song->tags; },
$songs);
$tags = array_merge(...$tagss);
$tags = unique($tags);
printf("%s\n", json_encode($tags));
8: Generator
Yield
With procedural approach, we can also flatten tags.
We are going to consider this approach for concurrency topic.
Gather Take
Consider this function.
<?php
function sender($songs) {
foreach($songs as $song) {
foreach($song->tags as $tag) {
yield $tag;
}
}
}
Entry Point
Then we can call later:
<?php
# main: entry point
require_once(__DIR__.'/MyClassSongs.php');
$tags = iterator_to_array(
sender($songs), true);
printf("%s\n", json_encode($tags));
With the result of
❯ php 25-yield.php
["60s","jazz","60s","rock","70s","rock","70s","pop"]
9: Concurrency with Fibers
Available since PHP 8.1.
To be examined later.
To be concluded.
What is Next 🤔?
Consider continue reading [ Bash IFS - Playing with Records - Part One ].