之前试过发布这个,但我要试着重新说一遍。
假设我有一个多维数组,我想在移动到每个数组的第二个元素之前影响每个数组的第一个元素。
我有一个项目数组,其中键是订单#,值是完成订单所需的小时数。
Array
(
[100 Series] => Array
(
[Order1] => 6
[Order2] => 6
[Order3] => 6
[Order4] => 6
[Order5] => 6
[Order6] => 6
[Order7] => 6
[Order8] => 6
)
[50 Series] => Array
(
[Order1] => 4
[Order2] => 4
[Order3] => 4
[Order4] => 4
)
)
然后我有一群人,他们有时间表和项目可以做:
Array
(
[Eric Smith] => Array
(
[Schedule] => Array
(
[Monday] => 8
[Tuesday] => 8
[Wednesday] => 8
[Thursday] => 8
[Friday] => 6
[Saturday] => 0
[Sunday] => 0
)
[Projects] => Array
(
[0] => 100 Series
[1] => 50 Series
)
)
)
我想用日期,项目名称,订单号,然后是人员姓名和他们在该项目上工作的时间来填充工作流数组,它看起来像这样:
Array
(
[Monday] => Array
(
[100 Series] => Array
(
[Order1] => Array
(
[Eric Smith] => 6
)
)
[50 Series] => Array
(
[Order1] => Array
(
[Eric Smith] => 2
)
)
[Tuesday] => Array
(
[50 Series] => Array
(
[Order1] => Array
(
[Eric Smith] => 2
)
)
[100 Series] => Array
[Order2] => Array
(
[Eric Smith] => 6
)
)
)
那么订单数组应该是这样的:
Array
(
[100 Series] => Array
(
[Order1] => 0
[Order2] => 0
[Order3] => 6
[Order4] => 6
[Order5] => 6
[Order6] => 6
[Order7] => 6
[Order8] => 6
)
[50 Series] => Array
(
[Order1] => 0
[Order2] => 4
[Order3] => 4
[Order4] => 4
)
)
现在它只是移动到第一个项目数组顺序1-8,然后移动到第二个项目。我希望它先完成orders->项目数组中的所有第一个元素,然后再移动到每个项目中的第二个元素。
我希望这是有意义的!
如果你发布了你现在正在使用的代码,那可能会有所帮助。我也不完全清楚你到底想做什么。似乎有一个更好的方法,你可以实现整个事情比与多dim数组,但回答这个问题,这可能工作:
$index = 0;
start:
for ($i=0;i<count($projectArray);$i++){
if (count($project)<$index)goto finished; //or maybe continue;
//you may need some extra conditionals, but that depends on what you want to be terminating the loop
$project = $projectArray[$i];
$item = $project[$index]; //then do what you want with $item
}
$index++;
//if you are not finished
goto start;
finished:
//the rest of your code
如果我们假设你的帖子中的第一个数组称为$projects;
,你的工作流数组称为$workflow;
您将需要以下内容:
// first loop $workflow and create an array that can be processed more easily
$data = array();
foreach($workflow as $day => $project){
foreach($project as $projectName => $projectDetails){
foreach($projectDetails as $orderNumber => $person){
foreach($person as $hours){
$data[$orderNumber][$projectName] = $hours;
}
}
}
}
// print_r($data) shows new array that is ordered in terms of order => project => hours
// now update your $projects array with this $data
foreach($data as $key => $project){
foreach($project as $projectName => $projectHours){
$projects[$projectName][$key] -= $projectHours;
}
}
// print_r($projects) to see that the project hours have decreased appropriately
我知道深嵌套的foreach循环并不理想,但您尝试使用的方法也不理想。我认为这是最好的解决办法。
查看array_walk_recursive
你可以使用一个回调函数来检查这个值是否不是数组本身,而是数组的第一个值。
编辑Array_walk_recursive似乎是无用的,因为它不传递任何关于您在数组中的位置的信息。下面是我的walk函数:
class arr{
/**
* Iterate and traverse array and apply function to data
*
* example:
* $f = function($v, $k, $custom, $info){
* if(!is_array($v) && !obj::is($v)) {
* return $v." [ custom: {$custom['key']} ] [ level: ".$info['depth'].' | No '.$info['i'].' of '.$info['count']." ]";
* }
* return $v;
* };
*
* arr::walk($mixed,$f,['key'=>'value'],true)
*
* @param array $array
* @param function,array $callback
* @param mixed $custom
* @param integer,boolean $recursive
* @param boolean $deduce
* @param array $info
* @return array
*/
public static function walk(&$array, $callback, $custom = null, $recursive = true, $deduce = false, $info = [])
{
if (is_array($array)) {
$return = null;
if (array_key_exists('depth', $info)) {
$info['depth'] ++;
} else {
$info['depth'] = 1;
}
$info['count'] = count($array);
$info['i'] = 1;
$r = $recursive;
if (gettype($r) === 'integer') {
$r--;
}
foreach($array as $k => &$v) {
$inf = $info;
if ($info['depth'] > 0) {
$inf['path'][] = $k;
}
if ($return = $callback($v, $k, $custom, $inf, $array)) {
break;
}
if (is_array($v) && $r > 0) {
$return = arr::walk($v, $callback, $custom, $r, $deduce, $inf);
if ($return) {
break;
}
}
$info['i'] ++;
}
return $return;
}
}
}
你的实现应该看起来像这样:
$result = [];
arr::w($a, function($v,$k) use (&$result){
if(is_array($v) && !empty($v)){
$r = array_values($v)[0];
if(!is_array($r)){
$result[] = $r;
}
}
}
);