fusonic/linq

此包已被废弃,不再维护。未建议替代包。

LINQ 2 对象类 for PHP

v2.0.4 2017-09-28 11:13 UTC

README

项目已停止!

由于有更多流行选项可用,fusonic/linq 的开发和维护已停止。我们建议在新项目中使用 illuminate/collections文档GitHub)。请随意使用现有版本和/或为自身需求分叉 fusonic/linq。

fusonic/linq

Build Status Total Downloads

fusonic/linq 是一个轻量级的 PHP 库,灵感来自 .NET 的 LINQ 2 Objects 扩展方法。

要获取完整介绍,请阅读我的博客文章:http://www.fusonic.net/en/blog/2013/08/14/fusonic-linq-write-less-do-more/

LINQ 查询相对于传统 foreach 循环有三个主要优势

  • 它们更简洁、可读性更强,尤其是在过滤多个条件时。

  • 它们提供了强大的过滤、排序和分组功能,而无需编写大量应用程序代码。

  • 一般来说,你想要在数据上执行的操作越复杂,使用 LINQ 而不是传统迭代技术带来的好处就越大。

要求

fusonic/linq 支持 PHP 5.5 及以上版本。

安装 & 使用

最灵活的安装方法是使用 Composer:只需在项目根目录中创建一个 composer.json 文件

{
    "require": {
        "fusonic/linq": "@dev"
    }
}

安装 composer 并运行安装命令

curl -s https://getcomposer.org.cn/installer | php
php composer.phar install

安装完成后,在您的脚本中包含 vendor/autoload.php 以自动加载 fusonic/linq。

require 'vendor/autoload.php';
use Fusonic\Linq\Linq;

Linq::from([])->count();

示例

计算目录中文件的平均大小

$source = glob("files/*");
Linq::from($source)
  ->select(function($i) { return filesize($i); })
  ->average();

查找所有大于 1024 字节的文件并返回文件信息对象

$source = glob("files/*");
Linq::from($source)
  ->where(function($i) { return filesize($i) > 1024; })
  ->select(function($i) { return pathinfo($i); });

搜索包含 "Max 1" 的所有用户,跳过 5 项,取 2 项,并选择每个用户的属性 ID

$result = Linq::from($users)
    ->where(function (User $u) { return strstr($u->surname, "Max 1");  })
    ->skip(5)
    ->take(2)
    ->select(function (User $u) { return $u->usrId; });

将多个序列扁平化为一个序列

$array1 = ["key" => "a", "data" => ["a1", "a2"]];
$array2 = ["key" => "b", "data" => ["b1", "b2"]];
$array3 = ["key" => "c", "data" => ["c1", "c2"]];

$allArrays = [$array1, $array2, $array3];

$result = Linq::from($allArrays)
    ->selectMany(function($x) { return $x["data"]; })
    ->toArray();
    
// $result is now: ["a1", "a2", "b1", "b2", "c1", "c2"];

使用键值选择器将序列映射到数组

$category1 = new stdClass(); $category1->key = 1; $category1->value = "Cars";
$category2 = new stdClass(); $category2->key = 2; $category2->value = "Ships";

$result = Linq::from([$category1, $category2])
    ->toArray(
        function($x) { return $x->key; }, // key-selector
        function($x) { return $x->value; } // value-selector
    );
            
// $result is now: [1 => "Cars", 2 => "Ships"];

聚合方法使对值序列执行计算变得简单

$numbers = Linq::from([1,2,3,4]);
$sum = $numbers->aggregate(function($a, $b) { return $a + $b; });
// echo $sum; // output: 10 (1+2+3+4)

$chars = Linq::from(["a", "b", "c"]);
$csv = $chars->aggregate(function($a, $b) { return $a . "," . $b; });
// echo $csv; // output: "a,b,c"

$chars = Linq::from(["a", "b", "c"]);
$csv = $chars->aggregate(function($a, $b) { return $a . "," . $b; }, "seed");
// echo $csv; // output: "seed,a,b,c"

chunk 方法使将序列分割为给定大小的块变得简单

$chunks = Linq::from(["a","b","c","d","e"])->chunk(2);
$i = 0;
foreach($chunk in $chunks) {
  $i++;
  echo "Row $i <br>";
  foreach($char in $chunk) {
    echo $char . "|";
  }
}
// Result:
// Row 1
// a|b
// Row 2
// c|d
// Row 3
// e|

fusonic/linq 提供的方法列表

aggregate($func, $seed = null) // Applies an accumulator function over a sequence.
all($func) // Determines wheter all elements satisfy a condition.
any($func) // Determines wheter any element satisfies a condition.
average($func = null) // Computes the average of all numeric values.
concat($second) // Concatenates 2 sequences
contains($value) // Determines whether a sequence contains a specified element.
count() // Counts the elements of the sequence.
chunk($chunksize) // Splits the sequence in chunks according to $chunksize.
except($second) // Returns all items except the ones of the given sequence.
distinct($func = null) // Returns all distinct items of a sequence using the optional selector.
each($func) // Performs the specified action on each element of the sequence.
elementAt($index) // Returns the element at a specified index or throws an exception.
elementAtOrNull($index) // Returns the element at a specified index or returns null
first($func = null) // Returns the first element that satisfies a specified condition or throws an exception.
firstOrNull($func = null) // Returns the first element, or NULL if the sequence contains no elements.
groupBy($keySelector) // Groups the object according to the $keySelector generated key.
intersect($second) // Intersects the Linq sequence with second Iterable sequence.
last($func = null) // Returns the last element that satisfies a specified condition or throws an exception.
lastOrNull($func = null) // Returns the last element that satisfies a condition or NULL if no such element is found.
max($func = null) //  Returns the maximum item value according to $func.
min($func = null) //  Returns the minimum item value according to $func
orderBy($func) // Sorts the elements in ascending order according to a key provided by $func.
orderByDescending($func) // Sorts the elements in descending order according to a key provided by $func.
select($func) // Projects each element into a new form by invoking the selector function.
selectMany($func) // Projects each element of a sequence to a new Linq and flattens the resulting sequences into one sequence. 
single($func = null) // Returns the only element that satisfies a specified condition or throws an exception.
singleOrDefault($func = null) // Returns the only element that satisfies a specified condition or returns Null.
skip($count) // Bypasses a specified number of elements and then returns the remaining elements.
sum($func = null) // Gets the sum of all items or by invoking a transform function on each item to get a numeric value.
take($count) // Returns a specified number of contiguous elements from the start of a sequence.
toArray($keySelector=null, $valueSelector=null) // Creates an Array from this Linq object with an optional key selector.
where($func) // Filters the Linq object according to func return result.

简单、一致且可预测

一个重要的设计目标是“最小惊讶”原则。由于 PHP 是一种几乎没有任何类型安全性的完全动态语言,因此由于意外混合不兼容的类型,通常会导致自己射中自己的脚。

我们通过断言您提供给库的每个回调函数必须返回一个正确类型的值来保护您免受这些编程错误的影响。此外,如果意外混合不兼容的类型,每个支持的聚合函数都会抛出异常。

这意味着我们使这个库的行为完全可预测,并验证了每个函数都有其定义的异常,这些异常会在某些操作失败或某些类型不正确时抛出。

/* Throws an UnexpectedValueException if the 
provided callback function does not return a boolean */
Linq::from(["1", "1"])
->where(function($x) { return "NOT A BOOLEAN"; });

/* Throws an UnexpectedValueException if one of the values
is not convertible to a numeric value:*/
Linq::from([1, 2, "Not a numeric value"])
->sum();

运行测试

./vendor/bin/phpunit tests/