encase / functional
功能性强、流畅且高效
Requires
- php: ^8.1
- ext-mbstring: *
Requires (Dev)
- mockery/mockery: ^1.3
- phpunit/phpunit: ^8.5.23
Suggests
- encase/regex: Regex pattern integration in functions such as split().
This package is auto-updated.
Last update: 2024-09-29 05:09:28 UTC
README
受...启发,但在技术上不是函数式编程。
概述
此库受到了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 反射类的功能。对任何需要反射的方法的第一个调用会适当实例化一个新的 ReflectionMethod
或 ReflectionFunction
对象,并将其存储在内部以供将来调用。可以使用 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
盒子: int
、float
、bool
(转换: string
)
类似于 JavaScript 中的 Number 类,这是一个值包装器,可以以函数式方式管理整数和浮点值。
字符串
扩展: Value
盒子: string
(转换: int
、float
、bool
)
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
。
值
实现接口:ArrayAccess
、Countable
、IteratorAggregate
、JsonSerializable
装箱:object
任何类型的值包装器,可用于以函数式方式处理任何类型的值。这是所有其他值包装器的基础,这些值包装器主要设计用于改进此类的行为、进行类型断言和允许更好的类型识别。此类使用 Encase\Functional\Functional
特性来允许将方法调用代理到函数调用。
除了实现的接口类之外,它还提供将包含的值转换为字符串和将包含的值作为函数调用的魔术方法。显然,包含的值必须实际支持这些操作。
静态方法
box(): Collection|Func|Number|Str|Value
- 见装箱
方法
boxIt(): BoxIterator
-getBoxIterator()
的方便简写别名count(): int
- 调用包含值的 sizeequals($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
上,例如 string
或 array
(或其他 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
遍历 iterable
、string
(请参阅 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 时匹配。如果 $pred
是 null
,则匹配第一个真值。否则,$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 \Closure
或instanceof \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
不是一个 iterable
或 string
,则返回 0。
slice
slice(iterable|\Traversable|string $value, ?int $start, int $end = null): iterable|\Traversable|string
提取 array
、string
或 \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']