PHP如何将嵌套的foreach变成数组的数组(多维数组)

Posted

技术标签:

【中文标题】PHP如何将嵌套的foreach变成数组的数组(多维数组)【英文标题】:PHP How To Turn Nested Foreach Into An Array of Arrays (Multidimensional Array) 【发布时间】:2019-04-03 03:50:31 【问题描述】:

我很抱歉,因为我可能不会在这里使用正确的词汇,但我正在尝试找出“如何”修改以下代码,以便它创建数组数组(多维数组) .这段代码创建了下图所示的结构,但我希望它创建数组数组(多维数组)。

基本上,我希望 1001、1002、1004 等......成为主数组。嵌套数组将是其中包含 #1001、#1002 等的字符串。您会注意到字符串中的 # 对应于原始数组中的数字。

$combinedAssignmentData = []; 
foreach($assignmentsYES as $key=>$assignedIDs)
  $levels = array($assignedIDs);
    foreach($levels as $key=>$level)
      echo "<strong>$level</strong><br>";
      foreach($studentIDsubmissions as $k=>$individualSubmission)
        if (strpos($individualSubmission, $level) !== false) 
          echo "--$individualSubmission<br>";
        
      
    

var_export($assignmentsYES);

array ( 0 => '1001', 1 => '1002', 2 => '1004', 3 => '1005', 4 => '1007', 5 => '1008', 6 => '1009', 7 => '1015', 8 => '1028', 9 => '1029', )

var_export($studentIDsubmissions);

array ( 0 => '346623@guhsd.net|TD-Share Test #1001|NO', 1 => '346623@guhsd.net|TD-Share Test #1001|NO', 2 => '346623@guhsd.net|TD-Share Test #1001|NO', 3 => '346623@guhsd.net|TD-Share Test #1001|NO', 4 => '346623@guhsd.net|TD-No Excuse Reflection #1002|YES', 5 => '346623@guhsd.net|TD-No Excuse Reflection #1002|YES', 6 => '346623@guhsd.net|TD-No Excuse Reflection #1002|YES', 7 => '346623@guhsd.net|TD-About Me #1004|YES', 8 => '346623@guhsd.net|TD-Calendar #1007|YES', 9 => '346623@guhsd.net|TD-Wage Tracker #1008|YES', 10 => '346623@guhsd.net|TD-Stock Portfolio #1009|YES', 11 => '346623@guhsd.net|TD-Collaboration #1005|YES', 12 => '346623@guhsd.net|TD-Stock Portfolio #1009|YES', 13 => '346623@guhsd.net|TD-Collaboration #1005|YES', 14 => '346623@guhsd.net|TD-Dream Vacation Presentation #1015|YES', )

非常感谢任何帮助! 托德

【问题讨论】:

如果你有这个$assignmentsYES的一些样本数据会容易得多(使用var_export,如果你添加任何) @ArtisticPhoenix,感谢您的帮助!我已经添加了数据。 其实我在你发布数据之前就已经写好了……哈哈 【参考方案1】:

给你

$assignmentsYES = array ( 0 => '1001', 1 => '1002', 2 => '1004', 3 => '1005', 4 => '1007', 5 => '1008', 6 => '1009', 7 => '1015', 8 => '1028', 9 => '1029', );
$studentIDsubmissions = array ( 0 => '346623@guhsd.net|TD-Share Test #1001|NO', 1 => '346623@guhsd.net|TD-Share Test #1001|NO', 2 => '346623@guhsd.net|TD-Share Test #1001|NO', 3 => '346623@guhsd.net|TD-Share Test #1001|NO', 4 => '346623@guhsd.net|TD-No Excuse Reflection #1002|YES', 5 => '346623@guhsd.net|TD-No Excuse Reflection #1002|YES', 6 => '346623@guhsd.net|TD-No Excuse Reflection #1002|YES', 7 => '346623@guhsd.net|TD-About Me #1004|YES', 8 => '346623@guhsd.net|TD-Calendar #1007|YES', 9 => '346623@guhsd.net|TD-Wage Tracker #1008|YES', 10 => '346623@guhsd.net|TD-Stock Portfolio #1009|YES', 11 => '346623@guhsd.net|TD-Collaboration #1005|YES', 12 => '346623@guhsd.net|TD-Stock Portfolio #1009|YES', 13 => '346623@guhsd.net|TD-Collaboration #1005|YES', 14 => '346623@guhsd.net|TD-Dream Vacation Presentation #1015|YES', );

$combinedAssignmentData = []; 
foreach($assignmentsYES as $key=>>$level)
        $combinedAssignmentData[$level] = 
                array_filter(
                    $studentIDsubmissions,
                    function($item)use($level)
                        return strpos($item, '#'.$level) !== false;
                    
                );


print_r($combinedAssignmentData);

输出

Array
(
    [1001] => Array
        (
            [0] => 346623@guhsd.net|TD-Share Test #1001|NO
            [1] => 346623@guhsd.net|TD-Share Test #1001|NO
            [2] => 346623@guhsd.net|TD-Share Test #1001|NO
            [3] => 346623@guhsd.net|TD-Share Test #1001|NO
        )

    [1002] => Array
        (
            [4] => 346623@guhsd.net|TD-No Excuse Reflection #1002|YES
            [5] => 346623@guhsd.net|TD-No Excuse Reflection #1002|YES
            [6] => 346623@guhsd.net|TD-No Excuse Reflection #1002|YES
        )

    [1004] => Array
        (
            [7] => 346623@guhsd.net|TD-About Me #1004|YES
        )

    [1005] => Array
        (
            [11] => 346623@guhsd.net|TD-Collaboration #1005|YES
            [13] => 346623@guhsd.net|TD-Collaboration #1005|YES
        )

    [1007] => Array
        (
            [8] => 346623@guhsd.net|TD-Calendar #1007|YES
        )

    [1008] => Array
        (
            [9] => 346623@guhsd.net|TD-Wage Tracker #1008|YES
        )

    [1009] => Array
        (
            [10] => 346623@guhsd.net|TD-Stock Portfolio #1009|YES
            [12] => 346623@guhsd.net|TD-Stock Portfolio #1009|YES
        )

    [1015] => Array
        (
            [14] => 346623@guhsd.net|TD-Dream Vacation Presentation #1015|YES
        )

    [1028] => Array
        (
        )

    [1029] => Array
        (
        )

)

Sandbox

*PS 我在这里strpos($item, '#'.$level) 中添加了#,这将提高一点准确性。最好使用正则表达式(在数组过滤回调中)

function($item)use($level)
   return preg_match('/#'.$level.'\|/', $item); //match `#id|`

考虑例如将1001 匹配到 id 10012 ~ strpos 将只匹配1001 部分而不考虑。

如果子数组的奇数键错误,您可以将array_filter 包装在array_values(array_filter(....)); 中以重置它们。数组过滤器保留原始数组中的键。在大多数情况下,密钥并不重要,所以除非你真的需要,否则我不会担心。

更新

想了想发了这个

最好使用正则表达式

我们为什么不选择这个:

$assignmentsYES = array ( 0 => '1001', 1 => '1002', 2 => '1004', 3 => '1005', 4 => '1007', 5 => '1008', 6 => '1009', 7 => '1015', 8 => '1028', 9 => '1029', );
$studentIDsubmissions = array ( 0 => '346623@guhsd.net|TD-Share Test #1001|NO', 1 => '346623@guhsd.net|TD-Share Test #1001|NO', 2 => '346623@guhsd.net|TD-Share Test #1001|NO', 3 => '346623@guhsd.net|TD-Share Test #1001|NO', 4 => '346623@guhsd.net|TD-No Excuse Reflection #1002|YES', 5 => '346623@guhsd.net|TD-No Excuse Reflection #1002|YES', 6 => '346623@guhsd.net|TD-No Excuse Reflection #1002|YES', 7 => '346623@guhsd.net|TD-About Me #1004|YES', 8 => '346623@guhsd.net|TD-Calendar #1007|YES', 9 => '346623@guhsd.net|TD-Wage Tracker #1008|YES', 10 => '346623@guhsd.net|TD-Stock Portfolio #1009|YES', 11 => '346623@guhsd.net|TD-Collaboration #1005|YES', 12 => '346623@guhsd.net|TD-Stock Portfolio #1009|YES', 13 => '346623@guhsd.net|TD-Collaboration #1005|YES', 14 => '346623@guhsd.net|TD-Dream Vacation Presentation #1015|YES', );

$combinedAssignmentData = []; 
foreach($assignmentsYES as $key=>$level)
    $combinedAssignmentData[$level] = preg_grep('/#'.$level.'\|/', $studentIDsubmissions);


print_r($combinedAssignmentData);

使用 Preg Grep 比使用数组过滤器和带有正则表达式的回调要干净一些。我还意识到你有一个肤浅的循环 $levels = array($assignedIDs); 或基本上是 $levels = array($level); 或只是 $level

和之前一样的输出

Sandbox

【讨论】:

感谢您的帮助!您的解决方案有效,但我意识到我需要稍作改动,希望您能提供帮助。您的解决方案创建了一个“关联数组”,但我需要它是一个“索引数组”。您能否更新您的解决方案,以便它在相同结构中创建一个“索引数组”?再次感谢! 如果您可以向我展示预期输出的示例(最好作为问题的更新),我可以对其进行更新。 it creates an "Indexed Array" in the same structure 你可以直接使用array_values($combinedAssignmentData) 来移除密钥,或者将这一行$combinedAssignmentData[$level] = preg_grep(...) 更改为$combinedAssignmentData[] = preg_grep(...),也就是说这些密钥非常有用,而且很容易解决。例如,想知道给定 ID count($combinedAssignmentData[$id]) 中是否有项目 - 想想没有 ID 你将如何找到它.... 感谢您的信息!今天晚些时候我会处理这个。此外,我感谢您在解决方案和 cmets 中提供的额外见解。它们确实可以帮助学习语言和概念的人更好地理解解决方案。 当然,很高兴我能帮上忙!

以上是关于PHP如何将嵌套的foreach变成数组的数组(多维数组)的主要内容,如果未能解决你的问题,请参考以下文章

PHP foreach 与嵌套数组?

PHP:我需要嵌套的 foreach 循环还是多个数组?

打印嵌套数组关联数组php

thinkphp怎么将多维数组变成一维数组

PHP未设置嵌套数组的部分

使用递归函数获取多维php数组的新值和键