【问题标题】:Creating Multi-Dimensional Array Using SQL data使用 SQL 数据创建多维数组
【发布时间】:2017-01-31 16:24:22
【问题描述】:

我正在使用一个插件,它想在 javascript 中输入这样的数组:

var data = [
    {
        "id": 1,
        "name": "University1",
        "list": [
            {"id": 1, "name": "Dorms", "list": 
                [
                    {"id": 1, "name": "Dorm1"},
                    {"id": 2, "name": "Dorm2"}
                ]
            },
            {"id": 2, "name": "Off-Campus", "list":
                [
                    {"id": 1, "name": "North Campus"},
                    {"id": 2, "name": "East Campus"}
                ]
            }
        ]
    },
    {
        "id": 2,
        "name": "University2",
        "list": [
            {"id": 1, "name": "Dorms", "list": 
                [
                    {"id": 1, "name": "Dorm1"},
                    {"id": 2, "name": "Dorm2"}
                ]
            },
            {"id": 2, "name": "Off-Campus", "list":
                [
                    {"id": 1, "name": "North Campus"},
                    {"id": 2, "name": "East Campus"}
                ]
            }
        ]
    }
];

我的数组数据位于 SQL 数据库中。我无法在 php 中形成这个多维数组和/或使用 AJAX 传递它。

我的 javascript/jquery:

var locationsArray;
$.post( 
    'ajax/locationDropdown.php', 
    {
        //NO DATA THIS TIME
    },
    function (response) {
        console.log(response);
        parseResponse = $.parseJSON(response);
        var locationsArray = $.map(parseResponse, function(value, index) {
            return [value];
        });
        console.log(locationsArray);
    }
);

我的 php:

<?php 

include 'databaseConnection.php';

$sqlLD1 = '
    SELECT DISTINCT school
    FROM timeBlocks
    ORDER BY school ASC;
';

if (!$resultLD1 = $connection->query($sqlLD1)) {
    die ('There was an error running the queryLD1 [' . $connection->error . ']');
}

$locationArray = array(
    'id'=>array(),
    'name'=>array(),
    'list'=>array(
        'id'=>array(),
        'name'=>array(),
        'list'=>array(
            'id'=>array(),
            'name'=>array()
        )
    )
);
$i=0;
    while ($rowLD1 = $resultLD1->fetch_assoc()) {
        $school = $rowLD1["school"];
        $locationArray[$i][name] = $school;
        $sqlLD2 = '
            SELECT DISTINCT timeBlockLocation
            FROM timeBlocks
            WHERE school = "'.$rowLD1["school"].'"
            ORDER BY timeBlockLocation ASC;
        ';
        if (!$resultLD2 = $connection->query($sqlLD2)) {
            die ('There was an error running the queryLD2 [' . $connection->error . ']');
        }
            $j=0;
            while ($rowLD2 = $resultLD2->fetch_assoc()) {
                $timeBlockLocation = $rowLD2["timeBlockLocation"];
                $locationArray[$i][$j][name]=$timeBlockLocation;
                $sqlLD3 = '
                    SELECT DISTINCT timeBlockSubLocation
                    FROM timeBlocks
                    WHERE school = "'.$rowLD1["school"].'"
                    AND timeBlockLocation = "'.$rowLD2["timeBlockLocation"].'"
                    ORDER BY timeBlockSubLocation ASC;
                ';
                if (!$resultLD3 = $connection->query($sqlLD3)) {
                    die ('There was an error running the queryLD2 [' . $connection->error . ']');
                }
                    $k=0;
                    while ($rowLD3 = $resultLD3->fetch_assoc()) {
                        $timeBlockSubLocation = $rowLD3["timeBlockSubLocation"];
                        $locationArray[$i][$j][$k][name]=$timeBlockSubLocation;
                        $k++;
                }
                $j++;
        }
        $i++;
}

echo json_encode($locationArray);

?>

这会产生一个如下所示的数组:

{
  "0": {
    "0": {
      "0": {
        "name": "All Locations"
      },
      "name": "Off Campus"
    },
    "1": {
      "0": {
        "name": "Dorm1"
      },
      "1": {
        "name": "Dorm2"
      }
      "name": "Dorms"
    },
    "name": "University1"
  },
  "1": {
    "0": {
      "0": {
        "name": "All Locations"
      },
      "name": "Off-Campus"
    },
    "1": {
      "0": {
        "name": "Dorm1"
      },
      "name": "Dorms"
    }
    "name": "University2"
  },
  "id": [],
  "name": [],
  "list": {
    "id": [],
    "name": [],
    "list": {
      "id": [],
      "name": []
    }
  }
}

【问题讨论】:

    标签: javascript php jquery sql arrays


    【解决方案1】:

    从性能的角度来看,最好避免在嵌套循环中执行查询。通常,您可以通过将表连接在一起来完成此操作。幸运的是,您的所有结果都来自同一张表,因此您甚至不必这样做。您只需运行一个简单的查询:

    $sql = 'SELECT school, timeBlockLocation, timeBlockSubLocation
            FROM timeBlocks
            ORDER BY school, timeBlockLocation, timeBlockSubLocation';
    
    $query_result = $connection->query($sql);
    

    然后使用它们的值作为数组键来获取结果:

    while ($row = $query_result->fetch_assoc()) {
        $schools[$row['school']][$row['timeBlockLocation']][$row['timeBlockSubLocation']] = 1;
        // (1 is meaningless, just a placeholder)
    }
    

    使用查询结果中的值作为数组键,您可以轻松创建所需的结构并防止重复条目。 这会给你一个这样的数组:

    $schools = [
        'University1' => [
            'Dorms' => ['Dorm1' => 1, 'Dorm2' => 1],
            'Off-Campus' => ['East Campus' => 1, 'North Campus' => 1]
        ],
        'University2' => [
            'Dorms' => ['Dorm1' => 1, 'Dorm2' => 1],
            'Off-Campus' => ['East Campus' => 1, 'North Campus' => 1]
        ]
    ];
    

    因为您需要的最终结果的每一级都具有相同的格式,所以递归函数可以很好地将中间数组转换为该格式:

    function reformat($array) {
        $id = 1;
        foreach ($array as $key => $value) {
            $branch = ['id' => $id++, 'name' => $key];
    
            // recursively reformat each level
            if (is_array($value)) $branch['list'] = reformat($value);
    
            $branches[] = $branch;
        }
        return $branches;
    }
    
    $locationArray = reformat($schools);
    

    【讨论】:

    • 哇,这太棒了。我最初试图做这样的事情,但我无法完全理解它。这将永远是一小部分地点,所以我并不十分关心性能,但这绝对是做到这一点的方法。一旦我实施,我可能会在这里更改答案。
    • 我将它切换到您的代码,但我收到一个解析错误: $branch = ['id' => $id++, 'name' => $key] ;有什么想法吗?
    • 可能您使用的是不支持短数组语法的旧 PHP 版本。尝试改用array('id' =&gt; ...)
    • 啊,这个成功了,再次感谢你,这是最好的答案
    【解决方案2】:

    我不会完全重写它,而是指出一种更简洁的通用方法

    去掉$locationArray声明中的所有子数组,干脆做

    $locationArray = array();
    

    然后在您的外部循环中为每次迭代启动一个新数组。在嵌套循环中更新从外循环开始的数组,然后在外循环结束时更新主输出数组

    while ($rowLD1 = $resultLD1->fetch_assoc()) {
            $school = array(
                'id' => $rowLD1["id"],
                'name'=> $rowLD1["school"],
                'list' => array()
            );
           // school query
           while ($rowLD2 = $resultLD2->fetch_assoc()) {
               // add to current school list array
               $school['list'][] = array(
                    'prop1' => $rowLD2['prop1'],
                    'prop2' => $rowLD2['prop2']
               );
           }
    
           // now add $school to main array
          $locationArray[] = $school;
    }
    
    echo json_encode....
    

    【讨论】:

    • 哦,这很有意义,感谢简化它。我将尝试修复旧代码,只是为了学习,但我可能会将其转换为这个。我将返回结果。再次感谢!
    • 这可以使事情按正确的顺序排列。一直在想怎么建错数组,谢谢指点。
    • 我现在有机会真正深入研究结果,并且我看到较低级别的数组实际上是对象。我如何指定它们应该是数组?
    • json_encode() 将 php 关联数组转换为 json 对象表示法
    • 好的,这很有帮助,但不幸的是(插件似乎不喜欢那样)...再次感谢您的帮助,我将尝试实施全新的答案性能更轻松。
    【解决方案3】:

    在每一步声明数组,然后填充它。在这种情况下,不要使用计数器$i, $j 来推送值

    $arr1 = array(
        'id': <id>,
        ...
        'list': array()
    );
    
    while(<condition>){
        $arr1['list'][] = array(
            'id' => <list_id>
            ...     
        );
    }
    ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-04
      • 1970-01-01
      • 2011-08-19
      相关资源
      最近更新 更多