来自FP背景,现在学习PHP,我自然会缺少一些受欢迎的高阶函数。我想知道PHP中是否有类似Clojure的partition-by
这样的东西。这是其功能的官方描述:
(partition-by f)(partition-by f coll)
将
f
[一个函数]应用于coll
中的每个值,每次f
都将其拆分 返回一个新值。返回分区的延迟序列。返回一个 未提供任何收集状态时的状态转换器。
我不太在乎惰性和转换器部分(无论如何我想这在PHP中是不可能的,对吗?)我需要做的就是转换这样的数组:
[["year" => 2019, "val" => "foo"],
["year" => 2019, "val" => "bar"],
["year" => 2020, "val" => "baz"],
["year" => 2020, "val" => "boo)"]]
对此:
[[["year" => 2019, "val" => "foo"],
["year" => 2019, "val" => "bar"]],
[["year" => 2020, "val" => "baz"],
["year" => 2020, "val" => "boo)"]]]
即我想通过这样的函数将它们分组:
function getYear($pair)
{
return $pair["year"];
}
我还没有尝试自己编写类似的代码,但是我想知道PHP的功能库(甚至是内核?)中是否存在类似的代码。
答案 0 :(得分:1)
我不认为这是一种语言功能。至少我没有或找不到任何东西。
但是,(除非我误解了),这应该可以为您提供您所描述的结果,但要注意的是,必须首先通过分区值对初始数组进行排序:
$f = [
["year" => 2019, "val" => "foo"],
["year" => 2019, "val" => "bar"],
["year" => 2020, "val" => "baz"],
["year" => 2020, "val" => "boo)"]
];
var_dump(partitionMultidim($f, "year"));
function partitionMultidim(array $values, string $key):array{
$new = [];
$p = $values[0][$key]; // alternatively check if exists in loop and set if not
$partitionNum = 0;
foreach($values as $value){
// what is the current value?
$curPartitionVal = $value[$key]; // or getYear($b);
// has the value changed?
if ( $p !== $curPartitionVal ){
// set the next partition value
$p = $curPartitionVal;
// new partition index
$partitionNum++;
}
// add to the new array
$new[$partitionNum][] = $value;
}
return $new;
}
答案 1 :(得分:0)
这不作为语言功能存在。但是,有现成的类可以执行相同的操作。示例:
$f = [
["year" => 2020, "val" => "baz"],
["year" => 2019, "val" => "foo"],
["year" => 2019, "val" => "bar"],
["year" => 2020, "val" => "boo)"]
];
//https://github.com/jspit-de/tableArray
$newArr = tableArray::create($f)
->orderBy('year ASC,val ASC')
->fetchGroup(['year'])
;
//test output
echo '<pre>';
var_dump($newArr);
输出:
array(2) {
[2019]=>
array(2) {
[0]=>
array(2) {
["year"]=>
int(2019)
["val"]=>
string(3) "foo"
}
[1]=>
array(2) {
["year"]=>
int(2019)
["val"]=>
string(3) "bar"
}
}
[2020]=>
array(2) {
[2]=>
array(2) {
["year"]=>
int(2020)
["val"]=>
string(4) "boo)"
}
[3]=>
array(2) {
["year"]=>
int(2020)
["val"]=>
string(3) "baz"
}
}
}