我有2个数组,$fileArr
和$noteArr
。
$fileArr
是文件列表。一个文件可以链接到多个故事。因此,在此$fileArr
中,您看到的是我需要列出的每个故事的所有文件。请注意,CAR.jpg([processId]=>111
)已链接到[storyId]=>1
和[storyId]=>2
。因此,CAR.jpg将被列出两次。
我想记下$noteArr
的所有笔记,并通过匹配$fileArr
]将它们放入[processId
。因此,每个CAR.jpg实例将具有2个注释,而TRUCK.jpg将没有任何注释。
我当前的$ fileArr
Array
(
[0] => Array
(
[fileName] => CAR.jpg
[processId] => 111
[storyId] => 1
)
[1] => Array
(
[fileName] => CAR.jpg
[processId] => 111
[storyId] => 2
)
[2] => Array
(
[fileName] => TRUCK.jpg
[processId] => 222
[storyId] => 3
)
)
我当前的$ noteArr
Array
(
[0] => Array
(
[noteId] => 50
[note] => this is a note
[processId] => 111
)
[1] => Array
(
[noteId] => 51
[note] => and this is also a note
[processId] => 111
)
)
我想要的新数组,其中的注释通过匹配processId放置在文件下
Array
(
[0] => Array
(
[fileName] => CAR.jpg
[processId] => 111
[storyId] => 1
[notes] => Array
(
[50] => Array
(
[noteId] => 50
[note] => this is a note
[processId] => 111
)
[51] => Array
(
[noteId] => 51
[note] => and this is also a note
[processId] => 111
)
)
)
[1] => Array
(
[fileName] => CAR.jpg
[processId] => 111
[storyId] => 2
[notes] => Array
(
[50] => Array
(
[noteId] => 50
[note] => this is a note
[processId] => 111
)
[51] => Array
(
[noteId] => 51
[note] => and this is also a note
[processId] => 111
)
)
)
[2] => Array
(
[fileName] => TRUCK.jpg
[processId] => 222
[storyId] => 3
)
)
我可以通过下面编写的代码来完成此操作,但是不想在循环中使用循环。还有另一种方法可以实现这一目标吗?
我当前的代码(循环内循环)
$newArr = array();
$i = 0;
foreach($fileArr as $file){
$newArr[$i] = $file;
if(count($noteArr)>0){
foreach($noteArr as $note){
if($file['processId']==$note['processId']){
$newArr[$i]['notes'][$note['id']] = $note;
}
}
}
$i++;
}
答案 0 :(得分:1)
如果您想删除嵌套循环以减少执行时间,则可以通过两次通过来完成
// save items of noteArr for each processId
$temp = [];
foreach($noteArr as $k => $note) {
$temp[$note['processId']][] = $note;
}
// and add saved sub-arrays to the source one
$newArr = [];
$i = 0;
foreach($fileArr as $file){
$newArr[$i] = $file;
if(isset($temp[$file['processId']]))
$newArr[$i]['notes'] = $temp[$file['processId'];
$i++;
}
答案 1 :(得分:0)
没有嵌套循环,您可以创建一个函数并通过引用传递:
function addNote(array &$array, array $notes)
{
$array['notes'] = [];
foreach ($notes as $note)
{
if ($note['processId'] == $array['processId']) {
$array['notes'][] = $note;
}
}
return $array;
}
foreach ($fileArr as &$file) {
addNote($file, $notes);
}
var_dump($fileArr);
看到它在这里https://3v4l.org/u37UL
答案 2 :(得分:0)
嗨,我快速浏览一下如何解决您的问题。不幸的是,它最终陷入了嵌套循环,但是我不需要循环任何项目(在您的解决方案中,您循环每个文件的所有注释)两次。
function sortProcessId($a, $b)
{
return $a['processId'] <=> $b['processId'];
}
$newArr = [];
usort($fileArr, 'sortProcessId');
usort($noteArr, 'sortProcessId');
rsort($noteArr);
$currentProcessId = 0;
$currentNote = array_pop($noteArr);
$newArr = [];
foreach ($fileArr as $key => $file){
$newArr[$key] = $file;
if ($currentProcessId === $file['processId']) {
$newArr[$key]['notes'] = [ $newArr[--$key]['notes']];
continue;
}
$newArr[$key]['notes'] = [];
$currentProcessId = $file['processId'];
while ($file['processId'] == $currentNote['processId']) {
$newArr[$key]['notes'][$currentNote['noteId']] = $currentNote;
$currentNote = array_pop($noteArr);
}
}
var_dump($newArr);
附加说明: 我使用rsort来使用array_pop,它应该比array_shift
快答案 3 :(得分:0)
您可以在PHP中使用一堆数组函数。
array_walk($fileArr, function(&$item) use ($noteArr) {
$processId = $item['processId'];
$foundNotes = array_filter($noteArr, function($note) use ($processId) {
return $note['processId'] === $processId;
});
if (!empty($foundNotes)) {
$item['notes'] = $foundNotes;
}
});
这将使您的$fileArr
变成我认为您想要的。
FWIW 我不认为嵌套循环是一种坏方法。虽然这段代码可以按照您的要求解决问题,但我认为它很难理解。