encase/functional

功能性强、流畅且高效

dev-master 2022-03-29 22:26 UTC

This package is auto-updated.

Last update: 2024-09-29 05:09:28 UTC


README

受...启发,但在技术上不是函数式编程。

Build Status Latest Stable Version Total Downloads License

概述

此库受到了lodash、underscore.php和Laravel等的启发,结合了面向对象风格的接口和类型抽象,提供各种功能式编程功能。这使得函数式函数可以像对象的方法一样被调用,并且具有链式调用的额外优势。

还包括其他一些功能,以在PHP中以JavaScript般舒适的方式提供对函数式编程的额外支持,同时利用PHP的特性,包括“装箱”,这样POD类型就可以轻松安全地封装在对象中,并具有更大的灵活性。

存在以下功能类型

  • Collection 用于数组。
  • Func 用于函数(任何 callable - 这有助于区分可调用的字符串和数组)
  • Number 用于整数和浮点数。
  • Str 用于字符串。
  • Value 用于 任何 类型,包括对象。

所有非 Value 类型都继承自 Value

安装

使用composer安装

composer require encase/functional

示例

函数式函数与面向对象方法

所有功能函数和面向对象对象都在 Encase\Functional 命名空间下。类型以大写字母开头,而函数以小写字母开头,这是惯例。在 Encase\Functional 中的任何函数都可以作为 Functional 类型的方法调用,而无需导入函数。

use Encase\Functional\Str;
use function Encase\Functional\split;

$array = split('foo');        // returns: ['f', 'o', 'o']

$str = Str::new('foo');      // or: new Str('foo')
$array = $str->split();       // returns: new Collection(['f', 'o', 'o'])
$newStr = $str->join(',');    // returns: new Str('f,o,o')

正如您可能注意到的,当调用 split() 时,这两种方法有显著差异:函数调用返回一个普通的 array,而方法代理调用返回一个用于链式调用的 Collection 实例。即使您传递一个对象给函数,这也适用 - 在此示例中,返回的是普通的 array 而不是 Collection 实例

split(Str::new('foo'));      // returns: ['f', 'o', 'o']

如果您需要最小的开销速度,您可能更喜欢函数和POD类型,而不是面向对象的方法。没有功能函数会返回功能式面向对象对象。然而,面向对象和链式调用的便捷性也有其好处,可以编写更易读、更简洁的代码。

方法链

虽然功能对象方法主要只是代理对功能函数的调用,但它们也会在适当的情况下处理从功能对象到其他类型的任何必要类型转换,以允许直观的链式调用。

Str::new('a.b.c.d')->split('.')->join(',');   // returns: new Str('a,b,c,d')

不可变性

功能旨在减少可变性。这意味着大多数功能函数和方法不会修改其主题,而是返回一个应用了修改的新值。

在此示例中,使用 map() 函数返回一个新对象,其元素根据函数调用的结果进行替换,同时在这个过程中不修改 $array

$array = new Collection('f', 'o', 'o');

// Assigns new Collection(['b', 'a', 'a']) to $newArray:
$newArray = $array->map(function ($char) {
  return $char === 'f' ? 'b' : 'a';
});

$foo = $array->join('.');      // returns: new Str('f.o.o')
$baa = $newArray->join('.');   // returns: new Str('b.a.a')

字符串处理

这个库中的函数喜欢将字符串视为Unicode字符数组。因此,您可能在其他语言中知道仅适用于数组的许多函数同样适用于字符串。例如,substr/substring 函数不是必要的,因为 slice 在字符串和数组上都同样有效。

// forget that slice and split exist for a second...
$string = Str::new('he✔ll✖o');
$array = [];

$string->each(function ($char) {
  if ($char === '') return;
  $array[] = $char;
  if ($char === '') return false;
});

// $array === ['h' ,'e', 'l', 'l', '✖']

编码

UTF-8 是字符串最支持的编码。然而,由于大多数函数使用了 PHP 的 mb_* 函数,所以使用的编码基于您的 PHP 配置。无法按函数覆盖编码。

装箱

此库提供将各种 PHP 类型装箱到合适的函数对象类型的支持。例如,一个字符串可以很容易地使用 Encase\Functional\Value 类的 box 静态方法装箱到 Encase\Functional\Str 对象,而无需指定类型。

$str = Value::box('hello');   // returns: new Str('hello')
$str = box('hello');          // convenience function
$str->split();                // etc...

这是一个隐式装箱的例子。值也可以显式装箱,这允许从给定的类型进行转换。

$str = Str::box(123);         // returns: new Str('123')
$value = $str->get();         // returns: '123'

有关哪些函数对象类型装箱哪些原生类型以及接受的转换的文档,请参阅 类型 子部分的说明。

box 方法自动防止双重装箱,因此您永远不会遇到“boxception”。

装箱与通过 ::new() 构造的比较

函数对象类提供两种构造对象的静态方法,如上所述的 ::box(),以及 ::new(),它更类似于 PHP 的 new 操作符。例如,使用 Str::new('abc')::new 方法主要用于作为 new Str('abc') 的替代语法。使用此方法而不是操作符的主要优势是能够在不使用额外的括号的情况下链式调用方法,如下所示

(new Str('abc'))->split();  // unpleasant extra parentheses required
Str::new('abc')->split();   // similar to Rust and looks nice in editor

::new 方法可能还提供了原始 new 操作符构造所没有的其他功能。这些差异取决于特定的类。然而,通常 ::new() 方法会提供更多功能,而 new 操作符将尽可能简单地执行操作(意味着开销更小)。一般建议在性能不是主要问题时(除非需要额外功能)优先使用 ::new() 方法。

类型

此库中提供的多数类型都设计为以对象形式使用函数方法,类似于 JavaScript 的核心对象。许多类也有静态方法,截至编写时,它们仅用于以不同方式构建类的实例。

BoxIterator

一个数组迭代器,在访问元素时会将元素适当装箱。例如,在访问时,字符串元素会被装箱到 Str 实例,而数组则被装箱到 Collection 实例。

示例

$iterator = new BoxIterator(['--hello--', '--world--']);

foreach ($iterator as $str) {
  echo $str->apply(new Func('trim'), '-'), ' ';
}

// Output: hello world 

集合

扩展: Value
装箱: array

类似于 Laravel 集合,这是一个值包装器,可以用来以函数方式管理 PHP 数组。

如果将其构造函数传递给一个字符串,则该字符串将被拆分为 Unicode 字符数组。

Func

扩展: Value
装箱: callable

这仅用作函数对象的包装器,以区分 PHP 可调用对象,这些对象可以是字符串和数组,可以像函数一样调用。

它还可以用于包装 \Generator 实例。这些实例将被包装在一个闭包中,该闭包返回生成器的当前值并将其向前推进。

值得注意的是,由于 Func 实现了 __invoke 魔法方法,因此它被认为是 PHP 中的 callable,因此它通过了类型提示。

示例
区分字符串/可调用参数

function hello() {
    return 'hi';
}

fill([], 'hello', 3);              // result: ["hello", "hello", "hello"]
fill([], Func::box('hello'), 3);   // result: ["hi", "hi", "hi"]

包装生成器

$strGen = function() {
    for ($i = 0; true; ++$i) {
        yield fill('', \chr(\ord('a') + ($i % 26)), 4);
    }
};

fill([], $randomStrGen(), 3);       // result (example): [
                                    //   Generator Object &00000002dcab7d...
                                    //   Generator Object &00000002dcab7d...
                                    //   Generator Object &00000002dcab7d...
                                    // ]

fill([], Func::box($strGen()), 3);  // result: ["aaaa", "bbbb", "cccc"]

方法
Func 提供了一个接口,用于访问 PHP 反射类的功能。对任何需要反射的方法的第一个调用会适当实例化一个新的 ReflectionMethodReflectionFunction 对象,并将其存储在内部以供将来调用。可以使用 getReflection 方法检索该对象。

  • getNumberOfParameters(): int - 获取参数数量。
  • getNumberOfRequiredParameters(): int - 获取必需参数数量。
  • getReflection(): ReflectionFunctionAbstract - 获取反射对象。
  • isClosure(): bool - 检查函数是否是闭包。
  • isGenerator(): bool - 检查函数是否是生成器。
  • isInternal(): bool - 检查函数是否是 PHP 内部函数。
  • isMethod(): bool - 检查函数是否是方法。
  • isVariadic(): bool - 检查函数是否是可变参数函数。

InvalidTypeError

扩展: InvalidArgumentException

表示无效的参数,但设计得更像 PHP 抛出的 TypeError,当传递无效参数时。错误信息更具有帮助性,格式如下
参数 $arg 在 $func 中期望 $type,实际提供 $givenType,在 $file 文件的第 $line 行调用

反射用于自动确定 $arg 的参数索引和 $func 的名称,以及调用所在的文件和行。

可以使用静态方法 make 创建。

静态方法
InvalidTypeError::make(string|string[] $type, mixed $value, string $paramName, int $depth = 1): InvalidTypeError

返回一个 InvalidTypeError 的新实例,使用提供的参数生成错误信息。 $type 应该是接受的类型,或者是接受类型的数组。 $value 用于确定给定的类型。 $paramName 应该是传递给 $value 的变量的名称,并显示为 $ 前缀,用于确定参数索引。 $depth 可以用来指定应该回溯到源文件/行的错误级别。

数字

扩展: Value
盒子: intfloatbool(转换: string

类似于 JavaScript 中的 Number 类,这是一个值包装器,可以以函数式方式管理整数和浮点值。

字符串

扩展: Value
盒子: string(转换: intfloatbool

PHP 字符串的值包装器,可以以函数式方式管理整数和浮点值。

静态方法

  • new($str) - 从参数创建字符串
  • random($length = 16) - 创建指定长度的随机字符串

类型

表示 PHP 类型系统中的类型。PHP 的类型系统某种程度上包括了类型可以是“未知”的可能性(见 gettype)。对于这种可能不常见的情况,将 NULL 分配给此类的成员。

有关“未知”类型的信息以及它们可能自 PHP 7.2 以来不再可能的信息,请参阅此 StackOverflow 答案

此类实现了魔法方法 __toString(),它返回表示的类型名称或 'unknown type'(如果未知则为 NULL)。

公共成员

  • string|null $type - 表示的类型名称。如果类型未知则为 NULL
  • string|null $class - 表示的对象的类(如果 $type'object',否则为 NULL)。

静态方法

  • new($type, $class = null): Type - 创建一个表示类型 $type 和类 $class(如果 null 则表示没有类)的 Type
  • of($var): Type - 创建一个表示 $var 类型的 Type

如果调用未列出的任何其他静态方法,则解释为调用 new,其中静态方法名称是 $type 参数,静态调用的参数是 $class 参数。例如:

Type::int();               // equivalent to: Type::new('int')
Type::string();            // equivalent to: Type::new('string')
Type::object('My\Class');  // equivalent to: Type::new('object', 'My\Class')

方法

  • equals(Type $type): bool - 如果两个 Type 对象表示相同的类型,则返回 TRUE。如果不相同,或者任一类型是 "unknown",则返回 FALSE
  • is($var): bool - 如果给定变量的类型与此 Type 对象表示的类型相同,则返回 TRUE

实现接口:ArrayAccessCountableIteratorAggregateJsonSerializable
装箱:object

任何类型的值包装器,可用于以函数式方式处理任何类型的值。这是所有其他值包装器的基础,这些值包装器主要设计用于改进此类的行为、进行类型断言和允许更好的类型识别。此类使用 Encase\Functional\Functional 特性来允许将方法调用代理到函数调用。

除了实现的接口类之外,它还提供将包含的值转换为字符串和将包含的值作为函数调用的魔术方法。显然,包含的值必须实际支持这些操作。

静态方法

  • box(): Collection|Func|Number|Str|Value - 见装箱

方法

  • boxIt(): BoxIterator - getBoxIterator() 的方便简写别名
  • count(): int - 调用包含值的 size
  • equals($value): bool - 检查包含的值是否与 $value 松散相等
  • get($key = null, $default = null) - 获取包含的值(对于此类,$key$default 被忽略,但可能由子类使用)
  • getBoxIterator(): BoxIterator - 获取包含值的 BoxIterator。这对于 iterable 类型是有效的。
  • getIterator(): \Iterator - 获取包含值的 \Iterator
  • is($value): bool - 检查包含的值是否严格等于 $value
  • isEmpty(): bool - 检查包含的值是否为 empty()
  • isNull(): bool - 检查包含的值是否为 === null
  • make(...$value): Value - 创建 Value(或子类)的实例 - 如果传递了另一个 Value 实例并且它是唯一的参数,则返回其克隆 - 所有提供的参数都传递给构造函数

函数

这是库提供的函数列表。其中大多数在许多函数式语言和库中都很常见,尽管可能会有一些差异和附加功能。除非另有说明,否则这些函数不会修改传递给它们的任何参数。

所有函数都尽量最大限度地利用原生 PHP 功能,并旨在在使用上具有灵活性。一个例子是许多期望 array-like 对象的函数将接受字符串并将它们视为 Unicode 字符的数组。

请注意:大多数这些函数可以作为任何 Value-derived 类型(或使用 Encase\Functional\Functional 特性的用户类)的方法调用。当作为方法调用时,包含的值始终作为第一个参数传递给函数。

apply

apply(mixed $subject, callable $func, mixed ...$args): mixed

调用 $func,将 $subject 作为第一个参数传递(如果 $subject 是对象,则传递其克隆)。可选地,还可以传递更多参数($args),这些参数也将传递给 $func。然后从该函数返回 $func 的结果。使用此功能将不会更改 $subject

与PHP内部函数的行为差异

如果 $func 不是 Func 的实例,那么将使用 PHP 反射来确定该函数是否是内置的并且不是可变参数的,以及所需参数的数量。如果函数是内置的并且不是可变参数的,则使用所需的参数数量来调用 $func,无论传递给 apply() 的参数有多少。

为什么?为什么只使用所需参数?

其他功能函数,如 map(),在确保 $subject 不会被修改的情况下,使用 apply() 来执行回调操作。map() 将额外的参数传递给回调函数,这些参数可能会被函数忽略。因此,这会导致错误,因为传递了比预期更多的参数(并且这些参数对于可选参数来说是错误的类型)。

// Hypothetical code demonstrating what would happen if apply didn't change behaviour for internal PHP functions:
$array = ['this ', ' cannot ', ' work'];
map($array, 'trim');   // causes error: trim() expects at most 2 parameters, 3 given

而不是要求传递一个闭包,然后调用目标函数并使用正确的参数数量,apply() 将执行上述步骤,只传递所需的参数,这样 PHP 内部操作可以具有可预测性,这意味着上述代码将无需额外努力即可工作。

所以,如果你想在 apply() 中手动传递到内置函数的可选参数,只需将 'trim' 包裹在 Func 中即可。

apply('***success***', new Func('trim'), '*');  // result: 'success'

assertType

assertType(mixed $value, string|string[] $types, string $paramName)

断言 $value 的类型是 $types 中给出的类型之一。有关更多详细信息,请参阅 isType。此功能旨在用于静态类型提示不足的情况,例如允许传递多个可能的类型或允许无法表示为类型提示的类型或类型组合。

如果 $value 与任何给定类型都不匹配,则抛出 Encase\Functional\Exceptions\InvalidTypeError 异常,使用 $types, $value, $paramName 构建。有关更多详细信息,请参阅 InvalidTypeError

此函数不能作为方法调用。

box

box(mixed $value): Collection|Func|Number|Str|Value

Value::box 的别名,它接受 $value 并将其包裹在合适的 Functional 对象实例中。有关此概念详细信息,请参阅 Boxing

此函数不能作为方法调用。因为没有意义,因为这只是一个静态 Value 方法的别名。但是,您可以传递 Value 对象,以便将其提升为更合适的类型。

concat

concat(iterable|string $container, mixed ...$values): iterable|string

concat 将值附加到 $container 上,例如 stringarray(或其他 iterable)。支持多个参数,每个参数将依次连接。

示例

concat('hello', ' world');      // returns: 'hello world'
concat([1, 2], 3, 4, 5);        // returns: [1, 2, 3, 4, 5]
$str = box('Functional');
$array = [' is', ' neat'];
$str->concat(...$array);
$str->get();                    // returns: 'Functional is neat'

each

each(iterable|stdClass|string|null $iterable, callable $func): mixed

遍历 iterablestring(请参阅 String Treatment)或 stdClass,并为每个元素调用提供的函数,将值作为第一个参数,索引/键作为第二个参数,将主题作为第三个参数。

支持提前退出,通过返回任何非 null 值。在提前退出的情况下,返回 null$func 返回的值。

注意:如果 $func 接收引用并修改它,则 $subject 可能会被修改。

关联数组示例

$array = [
    'apples' => 'green',
    'tomatoes' => 'red',
    'lemons' => 'yellow'
];

each($array, function ($value, $key) {
    echo $key, ' are ', $value, "\n";
});

/* Output:
  apples are green
  tomatoes are red
  lemons are yellow
*/

字符串示例

$str = 'find ✔ the ✔ ticks';
$result = [];

each($str, function ($value, $index, $str) use (&$result) {
    if ($value === '') {
        $result[$index] = \mb_substr($str, $index);
    }
});

// $result === ['✔ the ✔ ticks', '✔ ticks']

提前退出示例

$array = '✔✔✔✖✔';

$result = each($array, $index, function ($value) {
  if ($value === '') {
    return 'error: '.$index;
  }
  return;
});

// $result === 'error: 3'

fill

fill(array|string|\Countable $container, $value, int $length = null): array|string

创建一个大小为 $length 的数组或字符串,并使用 $value 填充它。返回的类型与 $container 的类型相同。

字符串示例

fill('', '.', 3);   // returns: "..."

数组示例

fill([1, 2, 3], '.');   // returns: ['.', '.', '.']

生成器示例
$value 参数将在 Func 中被封装,如果 isType($value, ['function', 'Generator'])Func 允许 fill 将生成器作为函数调用,每次调用返回一个新的值并推进生成器。

$randomAlphaGen = function () {
    while (true) {
        yield \chr(random_int(0, 25) + \ord('a'));
    }
};
fill([], $randomAlphaGen(), 5);   // could return: ['l', 'g', 'n', 'q', 'o']

find

find(array|iterable|stdClass|string $value, mixed|\Closure|\Encase\Functional\Func $pred = null, int $offset = 0): array|bool

在容器中向前搜索给定的值或谓词匹配。返回一个类似 [$foundIndex, $foundValue] 的数组,其中 $foundIndex 是匹配的索引/键,$foundValue 是找到的实际值。如果 $pred 是一个函数(见 isType),它将使用每个值和索引/键调用,并在返回 true 时匹配。如果 $prednull,则匹配第一个真值。否则,$pred 被视为一个值,并使用以下谓词

function ($value) use ($pred) {
  return $value === $pred;
};

$offset 可以用来从某个索引开始搜索。如果 $offset 是负数,搜索从容器末尾开始。虽然这在非顺序索引数组和关联数组中效果很好,但它始终被视为索引而不是键。

带有数组 & 值的示例

$array = ['a' => false, 'b' => 1, 'c' => '1', 'd' => true, 'e' => false];
$match = find($array, true);  // returns: ['d', true]

带有字符串 & PHP 内部函数的示例

$string = 'ábcdefg';
$match = find($string, function ($value, $index) {
  return $value === 'e' && $index === 4;
});  // returns: [4, 'e']

带有 Unicode 字符串 & 谓词的示例

$string = 'ábcdefg';
$match = find($string, function ($value, $index) {
  return $value === 'e' && $index === 4;
});  // returns: [4, 'e']

带有 PHP 内部函数作为谓词的示例
请记住使用 Func 来封装字符串或数组值,否则它们将被视为要找到的值而不是谓词函数。只有值会被传递给 PHP 内部函数,这意味着可以轻松地使用各种 PHP 函数

$string = 'ABCdEFG';
find($string, new Func('ctype_lower'));   // returns: [3, 'd']
find($string, 'ctype_lower');             // returns: FALSE

first

first(\Traversable|iterable|string|stdClass|null $iterable): mixed|null

获取 $iterable 中第一个元素的价值。如果 $iterable 为空,则返回 null

$string = first('§abc');    // returns: §
$int = first([1, 2, 3]);    // returns: 1

isAssociativeArray

isAssociativeArray(mixed $value): bool

检查 $value 是否是一个数组并且被认为是关联的。请注意,这可能不符合您的预期,因为此函数认为 非顺序索引的数组,从 0 开始 是关联数组。因此,这与 isSequentialArray 相反,而不是 isIndexedArray

示例

isAssociativeArray(['a', 'b', 'c']);        // false
isAssociativeArray(['a' => 0]);             // true (has string keys)
isAssociativeArray([1 => 'a', 0 => 'b']);   // true (integer keys, but not ordered)
isAssociativeArray([1 => 'a', 2 => 'b']);   // true (first key is not 0)

isIndexedArray

isIndexedArray(mixed $value): bool

检查 $value 是否是一个数组并且是索引的。一个数组被认为是索引的,如果它只有从 0 到数组长度(不包括长度)的整数键,无论顺序如何。

换句话说,如果任何键不是有效的索引,它返回 FALSE。判断一个键是否是有效索引的方法是:如果使用了 \array_values,能否使用该键访问结果数组?

注意:PHP 不区分数字字符串键和整数,因此即使您使用数字字符串,只要数字符合这些规则,数组就是索引的。

示例

isIndexedArray(['a', 'b', 'c']);        // true: sequential and indexed
isIndexedArray([1 => 'b', 0 => 'a']);   // true: non-sequential, but indexed
isIndexedArray([1 => 'nope']);          // false: the key 1 is out of range

isSequentialArray

isSequentialArray(mixed $value): bool

检查 $value 是否是一个数组并且是顺序索引的。一个数组被认为是顺序索引的,如果它只有从 0 到数组长度(就像 isIndexedArray)的整数键,并且这些键是有序的。

示例

isSequentialArray([0 => 'a', 1 => 'b', 2 => 'c']);  // true: sequential and indexed
isSequentialArray([1 => 'a', 0 => 'b', 2 => 'c');   // false: indexes not in order

isType

isType(mixed $value, string|string[] $types): string|FALSE

确定 $value 是否是给定的 $types 之一。返回表示符合 $value 的第一个类型的字符串,否则返回 FALSE

类型名称可以是PHP中用作静态类型提示的任何内容,PHP内部is_*函数接受的类型,或者使用instanceof检查的类名。此外,还可以是function,这可以表示闭包或Encase\Functional\Func实例(这是为了区分字符串和数组,它们可能是可调用的)。

示例

isType(3.14, ['int', 'float']);           // returns: 'float'
isType(123, 'string');                    // returns: FALSE
isType('hi', 'scalar');                   // returns: 'scalar'
isType('print', ['callable', 'string']);  // returns: 'callable'
isType('print', ['function', 'string']);  // returns: 'string'
isType(new Func('print'), 'function');    // returns: 'function'
$str = new Str('print');
$str->isType(['callable']);               // returns: 'callable'

类型检查

  • array - is_array()
  • bool - is_bool()
  • callable - is_callable()
  • countable - is_array()instanceof \Countable(PHP <7.3时is_countable()进行填充)
  • double/float/real - is_float()
  • function - instanceof \Closureinstanceof \Encase\Functional\Func
  • int/integer/long - is_int()
  • null - is_null()
  • numeric - is_numeric()
  • object - is_object()
  • resource - is_resource()
  • scalar - is_scalar()
  • string - is_string()

任何其他值都视为类名,并使用instanceof运算符进行检查。

join

join(iterable|stdClass|array $iterable, ?string $separator = ',', string $lastSeparator = null): string

$iterable中的所有值连接成一个字符串,由$separator分隔。如果提供了$lastSeparator,则最后两个元素使用该分隔符而不是$separator - 如果只有两个元素,则仅使用$lastSeparator。如果为$separator指定了null,则默认回退到','

$array = ['you', 'me', 'them'];
join($array);                   // returns: 'you,me,them'
join($array, ', ', ' and ');    // returns: 'you, me and them'

last

last(\Traversable|iterable|string|stdClass|null $iterable): mixed|null

获取$iterable中最后一个元素的值。如果$iterable为空,则返回null

$collection = Collection::make(1, 2, 3);
$object = (object)['a' => 1, 'b' => 2, 'c' => 3];
last($collection);                    // returns: 3
last($collection->getIterator());     // returns: 3
last($object);                        // returns: 3
last('ábc§');                         // returns: '§'

map

map($iterable, callable|null $func = null, bool $preserveKeys = false)

复制$iterable,将每个元素替换为$func返回的值。通过apply调用$func,该函数对PHP内部函数提供了一些方便的异常,因此请参阅该函数以获取调用的详细信息。除了这些异常之外,$func在每个迭代中都会被调用,带上:元素值、元素索引/键和$iterable本身。默认情况下,结果数组会被重新索引 - 使用$preserveKeys以使结果数组使用与输入相同的键。

示例

用键替换元素值,重置键(实质上是array_keys)。

$values = ['a' => 1, 'b' => 2, 'c' => 3];

$result = map($values, function ($value, $key) {
    return $key;
});

// $result === ['a', 'b', 'c']

将数组中的每个元素乘以二,同时保留键。

$values = [1 => 1, 2 => 2, 4 => 4, 8 => 8];

$result = map($values, function ($value, $key) {
    return $value * 2;
}, true);

// $result === [1 => 2, 2 => 4, 4 => 8, 8 => 16]

从整个字符串数组中去除空白。

$values = [' trim ', ' these ', ' strings'];
map($values, 'trim');     // returns: ['trim', 'these', 'strings']

not

not(callable $predicate): \Closure

返回一个调用$predicate并对其返回值进行布尔取反的\Closure。因此,如果$predicate在调用时返回TRUE/真值,则返回FALSE,反之亦然。

pop

pop(array|string|\ArrayAccess|\Traversable|\stdClass &$arrayish): mixed

此函数会修改其输入。

$arrayish容器中移除最后一个元素并返回它。此函数通过引用接收输入并更改其长度。将字符串视为包含unicode字符的数组。

示例

从数组中弹出。

$array = [1, 2, 3];
pop($array);          // returns: 3
// $array === [1, 2]

从字符串中弹出。

$string = '✔✔✖';
pop($string);         // returns: ✖
// $string === '✔✔'

reduce

reduce($iterable, callable $reducer, mixed $initial = null): mixed

遍历 $iterable,每次调用 $reducer 来修改 $initial,并返回 $initial 的最终值。每次对 $reducer 的调用都会传入 $initial 的当前修改值,接着是 $iterable 元素的值,然后是键,最后是 $iterable 本身,并将返回值赋给 $initial,用于下一次调用,或从该函数返回。

示例:各种类型的默认行为

// default numeric behaviour is to sum all elements
reduce([1, 2, 3], 10);                // returns: 16
// default string behaviour is to concatenate all elemnts
reduce([' my', ' friend'], 'hello');  // returns: 'hello my friend'
// default array behaviour is to append all elemnts
reduce(['b', 'c'], ['a']);            // returns: ['a', 'b', 'c']
// otherwise, the latst $iterable element is returned
reduce(['a', 'b', 'c']);              // returns: 'c'

示例:使用自定义谓词

// returns the product: 1 * 2 * 3 * 4 = 24
reduce([2, 3, 4], 1, function ($current, $value, $key, $iterable) {
    return $current * $value;
});

shift

shift(array|string|\ArrayAccess|\Traversable|\stdClass &$arrayish): mixed

此函数会修改其输入。

$arrayish 容器中移除第一个元素并返回它。此函数通过引用接收输入并改变其长度。将字符串视为一个包含 Unicode 字符的数组。

示例

从数组中移除。

$array = [1, 2, 3];
shift($array);        // returns: 1
// $array === [1 => 2, 2 => 3]

从字符串中移除。

$string = '✔✖✖';
shift($string);       // returns: ✔
// $string === '✖✖'

size

size(iterable|string $value): int

别名:count

获取 $value 的大小。对于 iterable,大小将是元素的数量。对于 string,大小将是 Unicode 字符的数量。如果 $value 不是一个 iterablestring,则返回 0。

slice

slice(iterable|\Traversable|string $value, ?int $start, int $end = null): iterable|\Traversable|string

提取 arraystring\Traversable 对象的一部分。切分的可遍历对象作为数组返回。返回从 $start 开始到(但不包括)$end 的部分。

注意:与 PHP 的内部函数不同,此函数使用起始和结束索引来确定范围,而不是起始索引和大小。

示例

获取子字符串。

slice('Hello world', 0, 5);       // returns: 'Hello'
slice('Hello world', null, -6);   // returns: 'Hello'
slice('Hello world', 6);          // returns: 'world'
slice('Hello world', -5);         // returns: 'world'

获取数组切片。

$array = [
    'one' => 1,
    'two' => 2,
    'three' => 3,
    'four' => 4,
    'five' => 5,
];
$array = slice($array, 2, -1);
// $array === ['three' => 3, 'four' => 4]

split

split(string $string, string|\Encase\Regex\Regex $separator = '', int $limit = null): array

使用 $separator$string 分割成字符串数组。

如果 $separator 是 Encase Regex 库中的 \Encase\Regex\Regex 对象,则使用包含的正则表达式匹配分隔符。

示例

按逗号分割。

split('1,2,3,4', ',');      // returns: ['1', '2', '3', '4']
split('1,2,3,4', ',', 3);   // returns: ['1', '2', '3,4']

按正则表达式分割。

use \Encase\Regex\Regex;

$array = split('hel.lo|wor/ld', Regex::new('/[^\w]/'));

// $array === ['hel', 'lo', 'wor', 'ld']

take

take(string|iterable|\stdClass $iterable, int $count): string|iterable|\stdClass

获取 $iterable 的前 $count 个元素。相当于 slice($iterable, 0, $count)(见 slice)。

takeUntil

takeUntil(string|iterable|\stdClass $iterable, callable $predicate): string|iterable|\stdClass

takeWhile 相同,但应用了 not,因此当 $predicate 在调用时返回一个真值时停止。

takeWhile

takeWhile(string|iterable|\stdClass $iterable, callable $predicate): string|iterable|\stdClass

获取从开始到 $predicate 在调用时返回一个假值之前的 $iterable 的切片。与 each 中的调用方式相同,传递每个元素的值和键,然后是 $iterable

typeOf

typeOf(mixed $value): string

根据 PHP 的 is_* 检查哪个返回 true 来获取变量的类型(而不是使用 gettype)。对于闭包对象返回 'function',但不适用于其他可调用对象,因为这些是字符串和数组。

可能的返回值:array、bool、int、float、function、null、object、resource、string

union

union(...$arrayish): array

返回一个数组或字符串,该数组或字符串包含给定 $arrays 值中的唯一元素。字符串键始终被认为是唯一的,但数值键将根据值本身发生冲突。后面的值将覆盖前面的值。

示例

$default => ['flagA', 'flagC', 'speed' => 100, 'price' => 50];
$options => ['flagA', 'flagB', 'speed' => 50];
union($default, $options);
// returned: ['flagA', 'flagB', 'flagC', 'speed' => 50, 'price' => 50]

unique

unique(string|array|iterable|\Traversable|\stdClass $arrayish, bool $keepKeyed = false, int $sortFlags = \SORT_REGULAR): array|string

返回一个只包含每个唯一元素值的数组或字符串。如果 $keepKeyed 设置为 TRUE,则非数字键的元素可以存在重复值。 $sortFlags 决定了新数组如何排序,更多详情请参见 \sort

示例

字符串中的唯一字符。

unique('aabacbc');    // returns: "abc"

键数组中的唯一元素。

$array = ['val1', 'val2', 'key1' => 1, 'key2' => 1, 'key3' => 1, 'val1', 'val3']
unique($array);   // ['val1', 'val2', 'val3', 'key1' => 1, 'key2' => 1, 'key3' => 1]

values

values(\Traversable|iterable|stdClass|null $iterable): \Traversable|iterable|stdClass|null

重新索引可遍历对象、数组或对象。相当于在数组上调用 map($iterable)\array_values($iterable)

示例

$array = ['a' => 'apple', 'b' => 'ball', 'c' => 'cat'];
values($array);     // returns: ['apple', 'ball', 'cat']