SilverStripe 3.1循环关联数组

时间:2015-04-17 06:45:38

标签: arrays foreach silverstripe

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

它给我的输出是:

  

布局:约翰

     战略:约翰

     

管理层:马丁

在这个例子中,约翰有一份以上的工作。

如果一个人有多个工作,我想把工作分组。

这是我想要的输出:

  

布局和策略:约翰

     

管理层:马丁

//$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;
}

如何更改我的功能以达到我想要的输出?

1 个答案:

答案 0 :(得分:2)

一种可能的解决方案是在将数据添加到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",他们将被视为一个,因为我使用名称作为数组键。

此外,如果一个人有三个工作,它会将其列为"布局和战略与管理"。为了避免这种情况,我们需要将代码中的第二个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以及最后一项。