PHP:如何将一个关联数组合并到另一个多维数组的子数组中
PHP: how to merge one associative array into a sub-array of another multidimensional array
我有一个平面结果集,在 JSON 中看起来像这样:
[{
"LineItemNo": "1",
"SolNo": "SPE8E7-15-T-1379",
"St": "O",
"PartNo": "F13DBX\/SPX35\/4P",
"UnitPrice": "1.890"
}, {
"LineItemNo": "1",
"SolNo": "SPE8E7-15-T-1379",
"St": "O",
"PartNo": "CF13DD\/E\/835",
"UnitPrice": "1.920"
}, {
"LineItemNo": "1",
"SolNo": "SPE8E7-15-T-1379",
"St": "O",
"PartNo": "QT13\/35-4",
"UnitPrice": "1.770"
}, {
"LineItemNo": "2",
"SolNo": "SPE8E7-15-T-4309",
"St": "O",
"PartNo": "F13DBX\/SPX35\/4P",
"UnitPrice": "1.890"
}, {
"LineItemNo": "2",
"SolNo": "SPE8E7-15-T-4309",
"St": "O",
"PartNo": "CF13DD\/E\/835",
"UnitPrice": "1.920"
}, {
"LineItemNo": "2",
"SolNo": "SPE8E7-15-T-4309",
"St": "O",
"PartNo": "QT13\/35-4",
"UnitPrice": "1.770"
}]
我想改成这样:
{
"data": [{
"LineItemNo": "1",
"SolNo": "SPE8E7-15-T-1379",
"St": "O",
"Parts": [{
"PartNo": "F13DBX\/SPX35\/4P",
"UnitPrice": "1.890"
}, {
"PartNo": "CF13DD\/E\/835",
"UnitPrice": "1.920"
}, {
"PartNo": "QT13\/35-4",
"UnitPrice": "1.770"
}]
}, {
"LineItemNo": "2",
"SolNo": "SPE8E7-15-T-4309",
"St": "O",
"Parts": [{
"PartNo": "F13DBX\/SPX35\/4P",
"UnitPrice": "1.890"
}, {
"PartNo": "CF13DD\/E\/835",
"UnitPrice": "1.920"
}, {
"PartNo": "QT13\/35-4",
"UnitPrice": "1.770"
}]
}]
}
我已经尝试了很多东西,但我一直无法找到一种方法来遍历源数组,在此过程中创建一个 Parts
数组,然后将值插入该数组随后的迭代。我想做的是迭代源数组,检查 $row['LineItemNo']
值,如果自上次迭代以来它发生了变化,则创建一个新的顶级数组对象。如果没有,则在 Parts
数组中创建一个新元素。
我的基本代码如下所示(我意识到 mysql 已被弃用,有利于 mysqli 或 PDO,但我暂时坚持使用它):
$result = mysql_query($query) or die(mysql_error());
$rs = array();
$rsParts = array();
while($row = mysql_fetch_array($result))
{
if (!isset($ln) || $row['LineItemNo'] != $ln)
{
$ln = $row['LineItemNo'];
$rs[data][] = array('LineItemNo' => $row['LineItemNo'], 'SolNo' => $row['SolNo'], 'St' => $row['St']);
$rs[data][parts] = array();
}
array_push($rs[data][parts], array('PartNo' => $row['PartNo'], 'UnitPrice' => $row['UnitPrice']));
}
这是一个好的开始,但它只给出了第一个元素中的部分,如下所示:
{
"data": {
"0": {
"LineItemNo": "1",
"SolNo": "SPE8E7-15-T-1379",
"St": "O"
},
"parts": [{
"PartNo": "F13DBX\/SPX35\/4P",
"UnitPrice": "1.890"
}, {
"PartNo": "CF13DD\/E\/835",
"UnitPrice": "1.920"
}, {
"PartNo": "QT13\/35-4",
"UnitPrice": "1.770"
}],
"1": {
"LineItemNo": "2",
"SolNo": "SPE8E7-15-T-4309",
"St": "O"
}
}
}
我认为您不能以这种方式重新初始化数组。我尝试在 LineItemNo 更改时取消设置它,但这会将所有 Parts
元素变成顶级元素。我尝试只在开始时使用 is_array
初始化数组,但这会将所有部分放入第一个顶级元素(第一个有六个部分,第二个有 none ).
那么,做我想做的事情的正确方法是什么?
编辑:问题的解决方案是首先通过以下代码发送结果集($result
):
$array = array();
while($r = mysql_fetch_assoc($result))
{
$array[] = $r;
}
然后从那里使用 SML 的解决方案。
array_push
是我通常采用的方式。你的代码读起来有点混乱(不是很用户友好),但我认为你很接近 - 非常接近...
编辑:查看以下内容。应该管用。将您的 while
更改为 foreach
和 运行,就像这样:
$rs = [];
foreach(mysql_fetch_array($result) as $key => $row)
{
$rs['data'][$key] = array('LineItemNo' => $row['LineItemNo'], 'SolNo' => $row['SolNo'], 'St' => $row['St']);
$part_info = array('part_no' => $row['PartNo'], 'unit_price' => $row['UnitPrice']);
$rs['data'][$key]['parts'] = $part_info;
}
print_r($rs);
假设任何给定的 LineItemNo
总是与相同的 SolNo
和 St
配对,您可以将每行的 LineItemNo
传递给函数以检查是否值存在于结果数组 $rs
.
的子数组中
如果 LineItemNo
不存在于 $rs
中,则创建一个新的 $rs
的第一级子数组和一个包含 parts info
的第二级子数组也将添加为第 1 级数组元素 parts
的 sub_array。
如果LineItemNo
确实存在,则只需将parts info
添加为第一级数组元素parts
的sub_array。
由于您在输出中想要的顶级数组 ['data'],在此阶段不执行任何操作。
我从流程中删除了它,而是在最后阶段将 $rs
添加到 $output['data']
以形成您需要的输出。
$rs=array();
$counter=0;
while($r = mysql_fetch_assoc($results)) {
$array[]=$r;
}
foreach ($array as $row) {
$part_info = array('part_no' => $row['PartNo'], 'unit_price' => $row['UnitPrice']);
$temp=searchSub ($rs, $row['LineItemNo']);
if ($temp===false){
$rs[$counter] = array('LineItemNo' => $row['LineItemNo'], 'SolNo' => $row['SolNo'], 'St' => $row['St']);
$rs[$counter]['parts'][] = $part_info;
$counter++;
}
else {
$rs[$temp]['parts'][]= $part_info;
}
}
//function for subarray search
function searchSub($arr, $keyword){
foreach($arr as $key=>$value)
{
if (in_array($keyword, $value, true)!=false){
return $key;
}
}
return false;
}
$output['data']=$rs;
print_r($output);
我有一个平面结果集,在 JSON 中看起来像这样:
[{
"LineItemNo": "1",
"SolNo": "SPE8E7-15-T-1379",
"St": "O",
"PartNo": "F13DBX\/SPX35\/4P",
"UnitPrice": "1.890"
}, {
"LineItemNo": "1",
"SolNo": "SPE8E7-15-T-1379",
"St": "O",
"PartNo": "CF13DD\/E\/835",
"UnitPrice": "1.920"
}, {
"LineItemNo": "1",
"SolNo": "SPE8E7-15-T-1379",
"St": "O",
"PartNo": "QT13\/35-4",
"UnitPrice": "1.770"
}, {
"LineItemNo": "2",
"SolNo": "SPE8E7-15-T-4309",
"St": "O",
"PartNo": "F13DBX\/SPX35\/4P",
"UnitPrice": "1.890"
}, {
"LineItemNo": "2",
"SolNo": "SPE8E7-15-T-4309",
"St": "O",
"PartNo": "CF13DD\/E\/835",
"UnitPrice": "1.920"
}, {
"LineItemNo": "2",
"SolNo": "SPE8E7-15-T-4309",
"St": "O",
"PartNo": "QT13\/35-4",
"UnitPrice": "1.770"
}]
我想改成这样:
{
"data": [{
"LineItemNo": "1",
"SolNo": "SPE8E7-15-T-1379",
"St": "O",
"Parts": [{
"PartNo": "F13DBX\/SPX35\/4P",
"UnitPrice": "1.890"
}, {
"PartNo": "CF13DD\/E\/835",
"UnitPrice": "1.920"
}, {
"PartNo": "QT13\/35-4",
"UnitPrice": "1.770"
}]
}, {
"LineItemNo": "2",
"SolNo": "SPE8E7-15-T-4309",
"St": "O",
"Parts": [{
"PartNo": "F13DBX\/SPX35\/4P",
"UnitPrice": "1.890"
}, {
"PartNo": "CF13DD\/E\/835",
"UnitPrice": "1.920"
}, {
"PartNo": "QT13\/35-4",
"UnitPrice": "1.770"
}]
}]
}
我已经尝试了很多东西,但我一直无法找到一种方法来遍历源数组,在此过程中创建一个 Parts
数组,然后将值插入该数组随后的迭代。我想做的是迭代源数组,检查 $row['LineItemNo']
值,如果自上次迭代以来它发生了变化,则创建一个新的顶级数组对象。如果没有,则在 Parts
数组中创建一个新元素。
我的基本代码如下所示(我意识到 mysql 已被弃用,有利于 mysqli 或 PDO,但我暂时坚持使用它):
$result = mysql_query($query) or die(mysql_error());
$rs = array();
$rsParts = array();
while($row = mysql_fetch_array($result))
{
if (!isset($ln) || $row['LineItemNo'] != $ln)
{
$ln = $row['LineItemNo'];
$rs[data][] = array('LineItemNo' => $row['LineItemNo'], 'SolNo' => $row['SolNo'], 'St' => $row['St']);
$rs[data][parts] = array();
}
array_push($rs[data][parts], array('PartNo' => $row['PartNo'], 'UnitPrice' => $row['UnitPrice']));
}
这是一个好的开始,但它只给出了第一个元素中的部分,如下所示:
{
"data": {
"0": {
"LineItemNo": "1",
"SolNo": "SPE8E7-15-T-1379",
"St": "O"
},
"parts": [{
"PartNo": "F13DBX\/SPX35\/4P",
"UnitPrice": "1.890"
}, {
"PartNo": "CF13DD\/E\/835",
"UnitPrice": "1.920"
}, {
"PartNo": "QT13\/35-4",
"UnitPrice": "1.770"
}],
"1": {
"LineItemNo": "2",
"SolNo": "SPE8E7-15-T-4309",
"St": "O"
}
}
}
我认为您不能以这种方式重新初始化数组。我尝试在 LineItemNo 更改时取消设置它,但这会将所有 Parts
元素变成顶级元素。我尝试只在开始时使用 is_array
初始化数组,但这会将所有部分放入第一个顶级元素(第一个有六个部分,第二个有 none ).
那么,做我想做的事情的正确方法是什么?
编辑:问题的解决方案是首先通过以下代码发送结果集($result
):
$array = array();
while($r = mysql_fetch_assoc($result))
{
$array[] = $r;
}
然后从那里使用 SML 的解决方案。
array_push
是我通常采用的方式。你的代码读起来有点混乱(不是很用户友好),但我认为你很接近 - 非常接近...
编辑:查看以下内容。应该管用。将您的 while
更改为 foreach
和 运行,就像这样:
$rs = [];
foreach(mysql_fetch_array($result) as $key => $row)
{
$rs['data'][$key] = array('LineItemNo' => $row['LineItemNo'], 'SolNo' => $row['SolNo'], 'St' => $row['St']);
$part_info = array('part_no' => $row['PartNo'], 'unit_price' => $row['UnitPrice']);
$rs['data'][$key]['parts'] = $part_info;
}
print_r($rs);
假设任何给定的 LineItemNo
总是与相同的 SolNo
和 St
配对,您可以将每行的 LineItemNo
传递给函数以检查是否值存在于结果数组 $rs
.
如果 LineItemNo
不存在于 $rs
中,则创建一个新的 $rs
的第一级子数组和一个包含 parts info
的第二级子数组也将添加为第 1 级数组元素 parts
的 sub_array。
如果LineItemNo
确实存在,则只需将parts info
添加为第一级数组元素parts
的sub_array。
由于您在输出中想要的顶级数组 ['data'],在此阶段不执行任何操作。
我从流程中删除了它,而是在最后阶段将 $rs
添加到 $output['data']
以形成您需要的输出。
$rs=array();
$counter=0;
while($r = mysql_fetch_assoc($results)) {
$array[]=$r;
}
foreach ($array as $row) {
$part_info = array('part_no' => $row['PartNo'], 'unit_price' => $row['UnitPrice']);
$temp=searchSub ($rs, $row['LineItemNo']);
if ($temp===false){
$rs[$counter] = array('LineItemNo' => $row['LineItemNo'], 'SolNo' => $row['SolNo'], 'St' => $row['St']);
$rs[$counter]['parts'][] = $part_info;
$counter++;
}
else {
$rs[$temp]['parts'][]= $part_info;
}
}
//function for subarray search
function searchSub($arr, $keyword){
foreach($arr as $key=>$value)
{
if (in_array($keyword, $value, true)!=false){
return $key;
}
}
return false;
}
$output['data']=$rs;
print_r($output);