SilverStripe 3.1 循环关联数组

SilverStripe 3.1 loop associative array

在 SilverStripe 3.1 中,我有一个循环遍历数组并输出其内容的函数。

它给我的输出是:

Layout: John

Strategy: John

Management: Martin

在这个例子中,约翰有不止一份工作。

如果一个人有不止一份工作,我想将这些工作分组。

这是我想要的输出:

Layout and Strategy: John

Management: Martin

//$InfoFieldArray = array('Layout' => 'John', 'Strategy' => 'John', 'Management' => 'Martin');

public function createInfoFields($InfoFieldArray){ 

    $Info = ArrayList::create();
    foreach($InfoFieldArray as $key => $value ){
        $fields = new ArrayData(array('FieldName' => $key, 'Value' => $value));
        $Info->push($fields);
    }   
    return $Info;
}

如何更改我的函数以获得所需的输出?

一个可能的解决方案是在将数据添加到 ArrayList 之前重组数据。

public function createInfoFields($InfoFieldArray)
{
    $info = array();

    foreach ($InfoFieldArray as $job => $person)
    {
        if (!isset($info[$person]))
        {
            $info[$person] = array();
        }

        $info[$person][] = $job;
    }

    $result = ArrayList::create();
    foreach ($info as $person => $jobs)
    {
        $fields = new ArrayData(array('FieldName' => implode(' and ', $jobs), 'Value' => $person));
        $result->push($fields);
    }

    return $result;
}

我所做的是遍历一组工作和分配的人,然后反过来,所以我有一组人和一份工作列表。这让我可以在 PHP 中调用 implode,通过 and.

这个词加入各种工作

有一些潜在的缺点,如果有两个名为 "John" 的人,他们将被视为一个人,因为我将姓名用作数组键。

另外,如果一个人有三份工作,它会像"Layout and Strategy and Management"一样列出。为避免这种情况,我们需要将代码中的第二个 foreach 循环修改为如下内容:

    foreach ($info as $person => $jobs)
    {
        $jobString = null;

        if (count($jobs) > 1)
        {
            $jobString = implode(', ', array_slice($jobs, 0, -1)) . ' and ' . array_pop($jobs);
        }
        else
        {
            $jobString = $jobs[0];
        }

        $fields = new ArrayData(array('FieldName' => $jobString, 'Value' => $person));
        $result->push($fields);
    }

当一个人有超过 1 个工作时,我们想要内爆(粘合在一起)$jobs 数组的数组片段,但是此时我们不需要最后一个元素。将数组粘合在一起后,我们将 and 附加到最后一项。