kllakk / yalinqo
YaLinqo,PHP对象的LINQ库
v2.4.2
2019-01-10 20:41 UTC
Requires
- php: >=5.5
Requires (Dev)
- phpdocumentor/phpdocumentor: ^2.8
- phpunit/phpunit: <6
- satooshi/php-coveralls: ^2.0
README
特性
- 最完整的.NET LINQ到PHP的端口,包含许多额外的方法。
- 延迟评估,错误消息以及原始LINQ的其他行为。
- 基于所有方法的PHPDoc和在线参考详细PHPDoc和在线参考。文章从MSDN的原始LINQ文档中改编而来。
- 100%单元测试覆盖率。
- 在所有功能的LINQ端口(YaLinqo、Ginq、Pinq)中性能最佳,至少比最接近的竞争者快2倍,参见性能测试。
- 回调函数可以作为闭包(如
function ($v) { return $v; }
)、PHP "函数指针"(字符串如'strnatcmp'
或数组如array($object, 'methodName')
)或使用各种语法的字符串 "lambdas"(如'"$k = $v"'
、'$v ==> $v+1'
、'($v, $k) ==> $v + $k'
、'($v, $k) ==> { return $v + $k; }'
)指定。 - 键和值同样重要。大多数回调函数接收键和值;可以对键和值应用转换;在转换过程中,键永远不会丢失(如果可能的话)。
- 在代码中使用SPL接口
Iterator
、IteratorAggregate
等,可以与 Enumerable 互换使用。 - 避免冗余的集合类,使用原生PHP数组。
- Composer支持(Packagist上的包)。
- 没有外部依赖。
实现的方法
由于名称是保留关键字,一些方法需要重命名。括号中给出原始方法名称。
- 生成:cycle、emptyEnum(空)、from、generate、toInfinity、toNegativeInfinity、matches、returnEnum(返回)、range、rangeDown、rangeTo、repeat、split;
- 投影和过滤:cast、ofType、select、selectMany、where;
- 排序:orderBy、orderByDescending、orderByDir、thenBy、thenByDescending、thenByDir;
- 连接和分组:groupJoin、join、groupBy;
- 聚合:aggregate、aggregateOrDefault、average、count、max、maxBy、min、minBy、sum;
- 集合:all、any、append、concat、contains、distinct、except、intersect、prepend、union;
- 分页:elementAt、elementAtOrDefault、first、firstOrDefault、firstOrFallback、last、lastOrDefault、lastOrFallback、single、singleOrDefault、singleOrFallback、indexOf、lastIndexOf、findIndex、findLastIndex、skip、skipWhile、take、takeWhile;
- 转换:toArray、toArrayDeep、toList、toListDeep、toDictionary、toJSON、toLookup、toKeys、toValues、toObject、toString;
- 动作:call(执行)、each(forEach)、write、writeLine。
总共超过80种方法。
示例
处理示例数据
// Data $products = array( array('name' => 'Keyboard', 'catId' => 'hw', 'quantity' => 10, 'id' => 1), array('name' => 'Mouse', 'catId' => 'hw', 'quantity' => 20, 'id' => 2), array('name' => 'Monitor', 'catId' => 'hw', 'quantity' => 0, 'id' => 3), array('name' => 'Joystick', 'catId' => 'hw', 'quantity' => 15, 'id' => 4), array('name' => 'CPU', 'catId' => 'hw', 'quantity' => 15, 'id' => 5), array('name' => 'Motherboard', 'catId' => 'hw', 'quantity' => 11, 'id' => 6), array('name' => 'Windows', 'catId' => 'os', 'quantity' => 666, 'id' => 7), array('name' => 'Linux', 'catId' => 'os', 'quantity' => 666, 'id' => 8), array('name' => 'Mac', 'catId' => 'os', 'quantity' => 666, 'id' => 9), ); $categories = array( array('name' => 'Hardware', 'id' => 'hw'), array('name' => 'Operating systems', 'id' => 'os'), ); // Put products with non-zero quantity into matching categories; // sort categories by name; // sort products within categories by quantity descending, then by name. $result = from($categories) ->orderBy('$cat ==> $cat["name"]') ->groupJoin( from($products) ->where('$prod ==> $prod["quantity"] > 0') ->orderByDescending('$prod ==> $prod["quantity"]') ->thenBy('$prod ==> $prod["name"]'), '$cat ==> $cat["id"]', '$prod ==> $prod["catId"]', '($cat, $prods) ==> array( "name" => $cat["name"], "products" => $prods )' ); // Alternative shorter syntax using default variable names $result2 = from($categories) ->orderBy('$v["name"]') ->groupJoin( from($products) ->where('$v["quantity"] > 0') ->orderByDescending('$v["quantity"]') ->thenBy('$v["name"]'), '$v["id"]', '$v["catId"]', 'array( "name" => $v["name"], "products" => $e )' ); // Closure syntax, maximum support in IDEs, but verbose and hard to read $result3 = from($categories) ->orderBy(function ($cat) { return $cat['name']; }) ->groupJoin( from($products) ->where(function ($prod) { return $prod["quantity"] > 0; }) ->orderByDescending(function ($prod) { return $prod["quantity"]; }) ->thenBy(function ($prod) { return $prod["name"]; }), function ($cat) { return $cat["id"]; }, function ($prod) { return $prod["catId"]; }, function ($cat, $prods) { return array( "name" => $cat["name"], "products" => $prods ); } ); print_r($result->toArrayDeep());
输出(压缩版)
Array (
[hw] => Array (
[name] => Hardware
[products] => Array (
[0] => Array ( [name] => Mouse [catId] => hw [quantity] => 20 [id] => 2 )
[1] => Array ( [name] => CPU [catId] => hw [quantity] => 15 [id] => 5 )
[2] => Array ( [name] => Joystick [catId] => hw [quantity] => 15 [id] => 4 )
[3] => Array ( [name] => Motherboard [catId] => hw [quantity] => 11 [id] => 6 )
[4] => Array ( [name] => Keyboard [catId] => hw [quantity] => 10 [id] => 1 )
)
)
[os] => Array (
[name] => Operating systems
[products] => Array (
[0] => Array ( [name] => Linux [catId] => os [quantity] => 666 [id] => 8 )
[1] => Array ( [name] => Mac [catId] => os [quantity] => 666 [id] => 9 )
[2] => Array ( [name] => Windows [catId] => os [quantity] => 666 [id] => 7 )
)
)
)
要求
- 版本1(稳定):PHP 5.3或更高版本。
- 版本2(稳定):PHP 5.5或更高版本。
- 版本3(预alpha):PHP 7.0或更高版本。
使用
添加到 composer.json
{ "require": { "athari/yalinqo": "^2.0" } }
添加到您的PHP脚本
require_once 'vendor/autoloader.php'; use \YaLinqo\Enumerable; // 'from' can be called as a static method or via a global function shortcut Enumerable::from(array(1, 2, 3)); from(array(1, 2, 3));
许可
简化版BSD许可
版权 © 2012–2018,亚历山大·普罗霍罗夫
版权所有。
链接
YaLinqo 文章
-
CodeProject (英文):
- LINQ for PHP比较:YaLinqo、Ginq、Pinq — 全功能LINQ端口的性能比较,附带一些附加信息。
-
Habrahabr (俄语):
- 旧LINQ库的比较 — 对 PHP LINQ、Phinq、PHPLinq 和 Plinq 的比较,还有 Underscore.php。
- YaLinqo 1.0 更新比较 — 架构和设计决策的解释。
- YaLinqo 2.0 — 转向支持生成器的PHP 5.5及其相关更改。
- PHP LINQ:速度很重要 — 全功能LINQ端口(YaLinqo、Ginq、Pinq)的性能比较。
-
其他 (英语):
- Tute Wall: 如何在PHP中使用LINQ 由 先生X 编写 — 一系列介绍YaLinqo基本使用的文章。
相关项目
- linq.js — JavaScript的LINQ。是.NET LINQ到JavaScript的唯一完整端口。
- Underscore.js — JavaScript函数式编程库。与LINQ类似,但方法名不同,且没有延迟求值。
- Underscore.php — Underscore.js到PHP的端口。
- RxPHP — LINQ的响应式(推送)对应物,Rx.NET的端口。
- YaLinqoPerf — 比较原始PHP、数组函数、YaLinqo、带有字符串lambda的YaLinqo、Ginq、具有属性访问器的Ginq、Pinq的性能测试集合。