perryflynn/perrys-lambda

该软件包已被弃用且不再维护。未建议替代软件包。

PHP 中的 lambda 表达式实现。

0.2.1 2018-02-03 12:53 UTC

This package is not auto-updated.

Last update: 2023-10-28 14:19:04 UTC


README

此项目试图在 PHP 中实现 C# .NET lambda 表达式。

Build Status Coverage Status

状态

开发中,API 半稳定。

Composer

Packagegist

composer require perryflynn/perrys-lambda

功能

  • 实现了许多类似 C# .NET 的 lambda 表达式
  • 支持自定义对象中记录的自动转换
  • 支持迭代和 foreach
  • 支持 生成器(帮助循环中的按引用调用)
  • 文件系统访问的辅助类
  • CSV 文件解析的辅助类

lambda 方法

方法 描述
*OrDefault 如果没有匹配项,则定义返回值,适用于许多方法
first 获取第一条记录
last 获取最后一条记录
single 获取单条记录,如果 count!=0,则抛出异常
take 获取前 X 条记录
skip 跳过前 X 条记录
where 通过 callable 表达式过滤记录
whereFirst 获取符合 callable 表达式的第一条记录
groupby 通过 callable 表达式分组记录
distrinct 通过 callable 表达式消除重复记录
intersect 返回两个 ArrayList 的交集
except 返回两个 ArrayList 的双向差异
any 如果 callable 表达式返回至少一个记录 true,则返回 true
all 如果 callable 表达式对所有记录返回 true,则返回 true
select 获取由 callable 表达式返回的值的 array
selectMany 获取所有值的 array,数组将合并
joinString 通过由 callable 表达式返回的值连接字符串
each 对每条记录执行 callable 表达式
sum 获取由 callable 表达式返回的数值返回值的总和
min 获取由 callable 表达式返回的数值返回值中的最小值
max 获取由 callable 表达式返回的数值返回值中的最大值
avg 获取由 callable 表达式返回的数值返回值的平均值
order 开始排序,升序,更多是通过 thenBy / thenByDesc 实现
orderDesc 开始排序,降序,更多是通过 thenBy / thenByDesc 实现

基本用法

$basic = new \PerrysLambda\ArrayList(array(1,2,3,4,5,6,7,8,9));

$basic->where(function($n) { return $n<=3; }); // Returns ArrayList of [1,2,3]
$basic->where(function($n) { return $n<=3; })->sum(); // Returns 6

使用 ObjectArray 和 Strings 替代 callables 的基本用法

$data = array(
    array('name'=>'Frank', age=>12),
    array('name'=>'Gene', age=>42),
    array('name'=>'Jessie', age=>31),
    array('name'=>'Carl', age=>55),
);

$list = \PerrysLambda\ArrayList::asObjectArray($data);
$list->select('age')->sum(); // Returns 140
$list->where(function($v) { return $v->age > 40; })->select('age')->sum(); // Returns 97

反序列化 / 序列化

  • 反序列化 json 数据
  • 修改数据
  • 再次序列化成 json 数据
  • 显示修改后的 json 数据
// examples/serialize.php

use PerrysLambda\ArrayList;
use PerrysLambda\ObjectArray;
use PerrysLambda\IArrayable;
use PerrysLambda\Converter\ItemConverter;
use PerrysLambda\Serializer\Serializer;
use PerrysLambda\Serializer\DateTimeSerializer;
use PerrysLambda\Serializer\BooleanSerializer;
use PerrysLambda\Converter\ListConverter;

// Testdata
$rawstring = <<<HEREDOC
{"foo":419995191,"bar":1492275950.5668,"foobar":"true","barfoo":"2018-12-08T20:24:41+0100","test":"Ivan"}
{"foo":92059366,"bar":1492275950.5669,"foobar":"false","barfoo":"2021-04-11T04:16:27+0200","test":"Gadget"}
{"foo":174207424,"bar":1492275950.5671,"foobar":"true","barfoo":"2017-07-29T21:53:36+0200","test":"Timmy"}
{"foo":624519809,"bar":1492275950.5672,"foobar":"false","barfoo":"2018-06-23T20:22:49+0200","test":"Alice"}
HEREDOC;

// Split into lines
$rawlines = explode("\n", $rawstring);

// Parse lines to one array with fields per line
$deserializer = function(&$row, &$key)
{
    if(is_string($row))
    {
        $data = json_decode($row, true);
        if(is_array($data))
        {
            $row = new ObjectArray($data);
        }
        else
        {
            return false;
        }
    }
    return true;
};

$serializer = function(&$row, &$key)
{
    if($row instanceof IArrayable)
    {
        $row = $row->toArray();
    }

    if(is_array($row))
    {
        $row = json_encode($row);
        if(is_string($row))
        {
            return true;
        }
    }
    return false;
};

// Row serializer
$fieldconverter = new ItemConverter();
$fieldconverter->setSerializer(new Serializer($serializer, $deserializer));

// Field serializer
$fieldconverter->setFieldSerializers(array(
    "barfoo" => DateTimeSerializer::fromIsoFormat(),
    "foobar" => new BooleanSerializer(),
));

// Create converter
$conv = new ListConverter();
$conv->setItemConverter($fieldconverter);
$conv->setArraySource($rawlines);

// Load raw data into ArrayList
$list = new ArrayList($conv);

// Modify data
$list
    ->where(function($v) { return $v->foobar===true; })
    ->each(function($v) { $v->foo = $v->foo+1; });

// Serialize modified data
$serlines = $list->serialize();
var_dump($serlines);

更多示例

查看单元测试