Giter Club home page Giter Club logo

functional-php's Introduction

Functional PHP: Functional primitives for PHP Build Status

A set of functional primitives for PHP, heavily inspired by Scala’s traversable collection, Dojo’s array functions and Underscore.js

  • Works with arrays and everything implementing interface Traversable
  • Consistent interface: for functions taking collections and callbacks, first parameter is always the collection, than the callback. Callbacks are always passed $value, $index, $collection. Strict comparison is the default but can be changed
  • Calls 5.3 closures as well as usual callbacks
  • C implementation for performance but a compatible userland implementation is provided if you can’t install PHP extensions
  • All functions reside in namespace Functional to not raise conflicts with any other extension or library

Installation

Install native extension

cd functional-php/
phphize
./configure
make
sudo make install

Use userland extension

Using composer

Put the require statement for functional-php in your composer.json file and run php composer.phar install:

{
    "require": {
        "lstrojny/functional-php": "*"
    }
}

Manually

Checkout functional-php and include the _import.php

<?php
include 'path/to/functional-php/src/Functional/_import.php';

Everytime you want to work with Functional PHP and not reference the fully qualified name, add use Functional as F; on top of your PHP file.

Overview

Functional\every() & Functional\invoke()

Functional\every(array|Traversable $collection, callable $callback)

array Functional\invoke(array|Traversable $collection, string $methodName[, array $methodArguments]) mixed Functional\invoke_first(array|Traversable $collection, string $methodName[, array $methodArguments]) mixed Functional\invoke_last(array|Traversable $collection, string $methodName[, array $methodArguments])

<?php
use Functional as F;

// If all users are active, set them all inactive
if (F\every($users, function($user, $collectionKey, $collection) {return $user->isActive();})) {
    F\invoke($users, 'setActive', array(false));
}

Functional\invoke_if()

mixed Functional\invoke_if(mixed $object, string $methodName[, array $methodArguments, mixed $defaultValue])

<?php
use Functional as F;

// if $user is an object and has a public method getId() it is returned,
// otherwise default value 0 (4th argument) is used
$userId = F\invoke_if($user, 'getId', array(), 0);

Functional\some()

bool Functional\some(array|Traversable $collection, callable $callback)

<?php
use Functional as F;

if (F\some($users, function($user, $collectionKey, $collection) use($me) {return $user->isFriendOf($me);})) {
    // One of those users is a friend of me
}

Functional\none()

bool Functional\none(array|Traversable $collection, callable $callback)

<?php
use Functional as F;

if (F\none($users, function($user, $collectionKey, $collection) {return $user->isActive();})) {
    // Do something with a whole list of inactive users
}

Functional\reject() & Functional\select()

array Functional\select(array|Traversable $collection, callable $callback)

array Functional\reject(array|Traversable $collection, callable $callback)

<?php
use Functional as F;

$fn = function($user, $collectionKey, $collection) {
    return $user->isActive();
};
$activeUsers = F\select($users, $fn);
$inactiveUsers = F\reject($users, $fn);

Alias for Functional\select() is Functional\filter()

Functional\drop_first() & Functional\drop_last()

array Functional\drop_first(array|Traversable $collection, callable $callback)

array Functional\drop_last(array|Traversable $collection, callable $callback)

<?php
use Functional as F;

$fn = function($user, $index, $collection) {
    return $index === 3;
};

// All users except the first three
F\drop_first($users, $fn);
// First three users
F\drop_last($users, $fn);

Functional\pluck()

Fetch a single property from a collection of objects or arrays.

array Functional\pluck(array|Traversable $collection, string|integer|float|null $propertyName)

<?php
use Functional as F;

$names = F\pluck($users, 'name');

Functional\partition()

Splits a collection into two by callback. Thruthy values come first

array Functional\partition(array|Traversable $collection, callable $callback)

<?php
use Functional as F;

list($admins, $users) = F\partition($collection, function($user) {
    return $user->isAdmin();
});

###Functional\group() Splits a collection into groups by the index returned by the callback

array Functional\group(array|Traversable $collection, callable $callback)

<?php
use Functional as F;

$groupedUser = F\group($collection, $function($user) {
    return $user->getGroup()->getName();
});

Functional\reduce_left() & Functional\reduce_right()

Applies a callback to each element in the collection and reduces the collection to a single scalar value. Functional\reduce_left() starts with the first element in the collection, while Functional\reduce_right() starts with the last element.

mixed Functional\reduce_left(array|Traversable $collection, callable $callback[, $initial = null])

mixed Functional\reduce_right(array|Traversable $collection, callable $callback[, $initial = null])

<?php
use Functional as F;

// $sum will be 64 (2^2^3)
$sum = F\reduce_left(array(2, 3), function($value, $index, $collection, $reduction) {
    return $reduction ^ $value;
}, 2);

// $sum will be 512 (2^3^2)
$sum = F\reduce_right(array(2, 3), function($value, $index, $collection, $reduction) {
    return $reduction ^ $value;
}, 2);

Functional\flatten()

Takes a nested combination of collections and returns their contents as a single, flat array. Does not preserve indexes.

array Functional\flatten(array|Traversable $collection)

<?php
use Functional as F;

$flattened = F\flatten(array(1, 2, 3, array(1, 2, 3, 4), 5));
// array(1, 2, 3, 1, 2, 3, 4, 5);

Functional\first_index_of()

Returns the first index holding specified value in the collection. Returns false if value was not found

array Functional\first_index_of(array|Traversable $collection, mixed $value)

<?php
use Functional as F;

// $index will be 0
$index = F\first_index_of(array('value', 'value'), 'value');

Functional\last_index_of()

Returns the last index holding specified value in the collection. Returns false if value was not found

array Functional\last_index_of(array|Traversable $collection, mixed $value)

<?php
use Functional as F;

// $index will be 1
$index = F\first_index_of(array('value', 'value'), 'value');

Functional\true() / Functional\false()

Returns true or false if all elements in the collection are strictly true or false

bool Functional\true(array|Traversable $collection) bool Functional\false(array|Traversable $collection)

<?php
use Functional as F;

// Returns true
F\true(array(true, true));
// Returns false
F\true(array(true, 1));

// Returns true
F\false(array(false, false, false));
// Returns false
F\false(array(false, 0, null, false));

Functional\truthy() / Functional\falsy()

Returns true or false if all elements in the collection evaluate to true or false

bool Functional\truthy(array|Traversable $collection) bool Functional\falsy(array|Traversable $collection)

<?php
use Functional as F;

// Returns true
F\truthy(array(true, true, 1, 'foo'));
// Returns false
F\truthy(array(true, 0, false));

// Returns true
F\falsy(array(false, false, 0, null));
// Returns false
F\falsy(array(false, 'str', null, false));

Functional\contains()

Returns true if given collection contains given element. If third parameter is true, the comparison will be strict

bool Functional\contains(array|Traversable $collection, mixed $value[, bool $strict = false])

<?php
use Functional as F;

// Returns true
F\contains(array('el1', 'el2'), 'el1');

// Returns false
F\contains(array('0', '1', '2'), 2);
// Returns true
F\contains(array('0', '1', '2'), 2, false);

Functional\zip()

Recombines arrays by index and applies a callback optionally

array Functional\zip(array|Traversable $collection1[, array|Traversable ...[, callable $callback]])

<?php
use Functional as F;

// Returns array(array('one', 1), array('two', 2), array('three', 3))
Functional\zip(array('one', 'two', 'three'), array(1, 2, 3));

// Returns array('one|1', 'two|2', 'three|3')
Functional\zip(
    array('one', 'two', 'three'),
    array(1, 2, 3),
    function($one, $two) {
        return $one . '|' . $two;
    }
);

Additional functions:

void Functional\each(array|Traversable $collection, callable $callback)
Applies a callback to each element

array Functional\map(array|Traversable $collection, callable $callback)
Applies a callback to each element in the collection and collects the return value

mixed Functional\first(array|Traversable $collection[, callable $callback])
mixed Functional\head(array|Traversable $collection[, callable $callback])
Returns the first element of the collection where the callback returned true. If no callback is given, the first element is returned

mixed Functional\last(array|Traversable $collection[, callable $callback])
Returns the last element of the collection where the callback returned true. If no callback is given, the last element is returned

mixed Functional\tail(array|Traversable $collection[, callable $callback])
Returns every element of the collection except the first one. Elements are optionally filtered by callback.

integer|float Functional\product(array|Traversable $collection, $initial = 1)
Calculates the product of all numeric elements, starting with $initial

integer|float Functional\ratio(array|Traversable $collection, $initial = 1)
Calculates the ratio of all numeric elements, starting with $initial

integer|float Functional\sum(array|Traversable $collection, $initial = 0)
Calculates the sum of all numeric elements, starting with $initial

integer|float Functional\difference(array|Traversable $collection, $initial = 0)
Calculates the difference of all elements, starting with $initial

integer|float|null Functional\average(array|Traversable $collection)
Calculates the average of all numeric elements

array Functional\unique(array|Traversable $collection[, callback $indexer[, bool $strict = true]])
Returns a unified array based on the index value returned by the callback, use $strict to change comparision mode

mixed Functional\maximum(array|Traversable $collection)
Returns the highest element in the array or collection

mixed Functional\minimum(array|Traversable $collection)
Returns the lowest element in the array or collection

mixed Functional\memoize(callable $callback[, array $arguments = array()], [mixed $key = null]])
Returns and stores the result of the function call. Second call to the same function will return the same result without calling the function again

Running the test suite

To run the test suite with the native implementation use php -c functional.ini $(which phpunit) tests/

To run the test suite with the userland implementation use php -n $(which phpunit) tests/

Mailing lists

Thank you

functional-php's People

Contributors

dsp avatar igorw avatar lstrojny avatar naderman avatar pierrejoye avatar rquadling avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.