Article Series

This article series discuss more than 30 different programming languages. Please read overview before you read any of the details.

Playing with Records Related Articles.

Where to Discuss?

Local Group

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:

  1. Exclude
  2. 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"]

PHP: Exclude Function

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: Solving Unique Song

❯ php 22-unique-b.php
["60s","jazz","rock","70s","pop"]

A Simpler Unique

With PHPs 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)
    );
  }
}

PHP: The Helper Module Containing Unique Function

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));

PHP: Solving Unique Song


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"]

PHP: Generator: Yield


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 ].