Avatar of rs1257

rs1257's solution

to Accumulate in the PHP Track

Published at Oct 04 2019 · 0 comments
Instructions
Test suite
Solution

Implement the accumulate operation, which, given a collection and an operation to perform on each element of the collection, returns a new collection containing the result of applying that operation to each element of the input collection.

Given the collection of numbers:

  • 1, 2, 3, 4, 5

And the operation:

  • square a number (x => x * x)

Your code should be able to produce the collection of squares:

  • 1, 4, 9, 16, 25

Check out the test suite to see the expected function signature.

Restrictions

Keep your hands off that collect/map/fmap/whatchamacallit functionality provided by your standard library! Solve this one yourself using other basic tools instead.

Running the tests

  1. Go to the root of your PHP exercise directory, which is <EXERCISM_WORKSPACE>/php. To find the Exercism workspace run

     % exercism debug | grep Workspace
    
  2. Get PHPUnit if you don't have it already.

     % wget --no-check-certificate https://phar.phpunit.de/phpunit.phar
     % chmod +x phpunit.phar
    
  3. Execute the tests:

     % ./phpunit.phar accumulate/accumulate_test.php
    

Source

Conversation with James Edward Gray II https://twitter.com/jeg2

Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.

accumulate_test.php

<?php

class AccumulateTest extends PHPUnit\Framework\TestCase
{
    public static function setUpBeforeClass() : void
    {
        require_once 'accumulate.php';
    }

    public function testAccumulateEmpty() : void
    {
        $accumulator = function ($value) {
            return $value ** 2;
        };

        $this->assertEquals([], accumulate([], $accumulator));
    }

    public function testAccumulateSquares() : void
    {
        $accumulator = function ($value) {
            return $value ** 2;
        };

        $this->assertEquals([1, 4, 9], accumulate([1, 2, 3], $accumulator));
    }

    public function testAccumulateUpperCases() : void
    {
        $accumulator = function ($string) {
            return mb_strtoupper($string);
        };

        $this->assertEquals(['HELLO', 'WORLD!'], accumulate(['Hello', 'World!'], $accumulator));
    }

    public function testAccumulateReversedStrings() : void
    {
        $accumulator = function ($string) {
            return strrev($string);
        };

        $this->assertEquals(['Hello', 'World!'], accumulate(['olleH', '!dlroW'], $accumulator));
    }

    public function testAccumulateConstants() : void
    {
        $accumulator = function () {
            return 1;
        };

        $this->assertEquals([1, 1], accumulate(['Hello', 'World!'], $accumulator));
    }

    public function testAccumulateWithinAccumulate() : void
    {
        $chars = ['a', 'b', 'c'];
        $digits = [1, 2, 3];
        $expected = [['a1', 'a2', 'a3'], ['b1', 'b2', 'b3'], ['c1', 'c2', 'c3']];

        $this->assertEquals(
            $expected,
            accumulate($chars, function ($char) use ($digits) {
                return accumulate($digits, function ($digit) use ($char) {
                    return $char.$digit;
                });
            })
        );
    }

    // Additional points for making the following tests pass

    public function testAccumulateUsingBuiltInFunction() : void
    {
        $this->assertEquals(['Hello', 'World!'], accumulate([" Hello\t", "\t World!\n "], 'trim'));
    }

    public function testAccumulateUsingStaticMethod() : void
    {
        $this->assertEquals([5, 6], accumulate(['Hello', 'World!'], 'Str::len'));
    }

    public function testAccumulateUsingInvoke() : void
    {
        $this->assertEquals([['f', 'o', 'o']], accumulate(['foo'], new StrSpliter()));
    }

    public function testAccumulateUsingObjectAndArrayNotation() : void
    {
        $this->assertEquals([true, false, false], accumulate(['Yes', 0, []], [new Is(), 'truthy']));
    }
}

class Str
{
    public static function len($string) : int
    {
        return strlen($string);
    }
}

class StrSpliter
{
    public function __invoke($value)
    {
        return str_split($value);
    }
}

class Is
{
    public function truthy($value) : bool
    {
        return $value ? true : false;
    }
}
<?php function accumulate(array $input, callable $accumulator){return array_map($accumulator, $input);}

Community comments

Find this solution interesting? Ask the author a question to learn more.

What can you learn from this solution?

A huge amount can be learned from reading other people’s code. This is why we wanted to give exercism users the option of making their solutions public.

Here are some questions to help you reflect on this solution and learn the most from it.

  • What compromises have been made?
  • Are there new concepts here that you could read more about to improve your understanding?