Clojure用PHP进行分区吗?

时间:2019-12-05 09:27:50

标签: php multidimensional-array functional-programming

来自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的功能库(甚至是内核?)中是否存在类似的代码。

2 个答案:

答案 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"
    }
  }
}