我有两个这样的数组:
Array1
{
"spider": [{
"urlsInScope": [{
"processed": "true",
"statusReason": "OK",
"method": "GET",
"reasonNotProcessed": "",
"messageId": "4",
"url": "http://192.168.2.131/",
"statusCode": "200"
},
{
"processed": "true",
"statusReason": "Unauthorized",
"method": "GET",
"reasonNotProcessed": "",
"messageId": "6",
"url": "http://192.168.2.131/login.php",
"statusCode": "401"
}]
},
{
"urlsOutOfScope": []
},
{
"urlsIoError": []
}],
"alerts": [{
"sourceid": "3",
"other": "The X-XSS-Protection HTTP response header allows the web server to enable or disable the web browser's XSS protection mechanism. The following values would attempt to enable it: \nX-XSS-Protection: 1; mode=block\nX-XSS-Protection: 1; report=http://www.example.com/xss\nThe following values would disable it:\nX-XSS-Protection: 0\nThe X-XSS-Protection HTTP response header is currently supported on Internet Explorer,
Chrome and Safari (WebKit).\nNote that this alert is only raised if the response body could potentially contain an XSS payload (with a text-based content type,
with a non-zero length).",
"method": "GET",
"evidence": "",
"pluginId": "10016",
"cweid": "933",
"confidence": "Medium",
"wascid": "14",
"description": "Web Browser XSS Protection is not enabled,
or is disabled by the configuration of the 'X-XSS-Protection' HTTP response header on the web server",
"messageId": "1",
"url": "http://192.168.2.131/",
"reference": "https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet\nhttps://blog.veracode.com/2014/03/guidelines-for-setting-security-headers/",
"solution": "Ensure that the web browser's XSS filter is enabled,
by setting the X-XSS-Protection HTTP response header to '1'.",
"alert": "Web Browser XSS Protection Not Enabled",
"param": "X-XSS-Protection",
"attack": "",
"name": "Web Browser XSS Protection Not Enabled",
"risk": "Low",
"id": "0"
},
{
"sourceid": "3",
"other": "This issue still applies to error type pages (401,
403,
500,
etc) as those pages are often still affected by injection issues,
in which case there is still concern for browsers sniffing pages away from their actual content type.\nAt \"High\" threshold this scanner will not alert on client or server error responses.",
"method": "GET",
"evidence": "",
"pluginId": "10021",
"cweid": "16",
"confidence": "Medium",
"wascid": "15",
"description": "The Anti-MIME-Sniffing header X-Content-Type-Options was not set to 'nosniff'. This allows older versions of Internet Explorer and Chrome to perform MIME-sniffing on the response body,
potentially causing the response body to be interpreted and displayed as a content type other than the declared content type. Current (early 2014) and legacy versions of Firefox will use the declared content type (if one is set),
rather than performing MIME-sniffing.",
"messageId": "1",
"url": "http://192.168.2.131/",
"reference": "http://msdn.microsoft.com/en-us/library/ie/gg622941%28v=vs.85%29.aspx\nhttps://www.owasp.org/index.php/List_of_useful_HTTP_headers",
"solution": "Ensure that the application/web server sets the Content-Type header appropriately,
and that it sets the X-Content-Type-Options header to 'nosniff' for all web pages.\nIf possible,
ensure that the end user uses a standards-compliant and modern web browser that does not perform MIME-sniffing at all,
or that can be directed by the web application/web server to not perform MIME-sniffing.",
"alert": "X-Content-Type-Options Header Missing",
"param": "X-Content-Type-Options",
"attack": "",
"name": "X-Content-Type-Options Header Missing",
"risk": "Low",
"id": "1"
},
{
"sourceid": "3",
"other": "",
"method": "GET",
"evidence": "",
"pluginId": "10020",
"cweid": "16",
"confidence": "Medium",
"wascid": "15",
"description": "X-Frame-Options header is not included in the HTTP response to protect against 'ClickJacking' attacks.",
"messageId": "1",
"url": "http://192.168.2.131/",
"reference": "http://blogs.msdn.com/b/ieinternals/archive/2010/03/30/combating-clickjacking-with-x-frame-options.aspx",
"solution": "Most modern Web browsers support the X-Frame-Options HTTP header. Ensure it's set on all web pages returned by your site (if you expect the page to be framed only by pages on your server (e.g. it's part of a FRAMESET) then you'll want to use SAMEORIGIN,
otherwise if you never expect the page to be framed,
you should use DENY. ALLOW-FROM allows specific websites to frame the web page in supported web browsers).",
"alert": "X-Frame-Options Header Not Set",
"param": "X-Frame-Options",
"attack": "",
"name": "X-Frame-Options Header Not Set",
"risk": "Medium",
"id": "2"
},
{
"sourceid": "3",
"other": "The X-XSS-Protection HTTP response header allows the web server to enable or disable the web browser's XSS protection mechanism. The following values would attempt to enable it: \nX-XSS-Protection: 1; mode=block\nX-XSS-Protection: 1; report=http://www.example.com/xss\nThe following values would disable it:\nX-XSS-Protection: 0\nThe X-XSS-Protection HTTP response header is currently supported on Internet Explorer,
Chrome and Safari (WebKit).\nNote that this alert is only raised if the response body could potentially contain an XSS payload (with a text-based content type,
with a non-zero length).",
"method": "GET",
"evidence": "",
"pluginId": "10016",
"cweid": "933",
"confidence": "Medium",
"wascid": "14",
"description": "Web Browser XSS Protection is not enabled,
or is disabled by the configuration of the 'X-XSS-Protection' HTTP response header on the web server",
"messageId": "6",
"url": "http://192.168.2.131/login.php",
"reference": "https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet\nhttps://blog.veracode.com/2014/03/guidelines-for-setting-security-headers/",
"solution": "Ensure that the web browser's XSS filter is enabled,
by setting the X-XSS-Protection HTTP response header to '1'.",
"alert": "Web Browser XSS Protection Not Enabled",
"param": "X-XSS-Protection",
"attack": "",
"name": "Web Browser XSS Protection Not Enabled",
"risk": "Low",
"id": "6"
}]
}
Array2
Array
(
[0] => Array
(
[ID] => 101
[Code] => 1075
[Date] => 2012-03-03 17:13:12.433
)
[1] => Array
(
[ID] => 103
[Code] => 175
[Date] => 2012-09-05 20:30:02.217
)
[2] => Array
(
[ID] => 109
[Code] => 178
[Date] => 2012-07-05 20:30:02.217
)
)
我使用此代码根据ID索引的匹配值将它们组合起来。
Array
(
[0] => Array
(
[Amount] => 1234
[ID] => 101
)
[1] => Array
(
[Amount] => 1342
[ID] => 103
)
[2] => Array
(
[Amount] => 0
[ID] => 0
)
)
这是我从这段代码中获得的期望输出:
$combined = array();
foreach ($arr as $arrs) {
$comb = array('ID' => $arrs['ID'], 'Code' => $arrs['Code'],'Date' => $arrs['Date'],'Amount' => '');
foreach ($arr4 as $arr2) {
if ($arr2['ID'] == $arrs['ID']) {
$comb['Amount'] = $arr2['Amount'];
break;
}
else {
$comb['Amount'] = $arr2['Amount'];
}
}
$combined[] = $comb;
}
echo print_r($combined);
我想优化代码,使
Array
(
[0] => Array
(
[ID] => 101
[Code] => 1075
[Date] => 2012-03-03 17:13:12.433
[Amount] => 1234
)
[1] => Array
(
[ID] => 103
[Code] => 175
[Date] => 2012-09-05 20:30:02.217
[Amount] => 1342
)
[2] => Array
(
[ID] => 109
[Code] => 178
[Date] => 2012-07-05 20:30:02.217
[Amount] => 0
)
)
应该动态生成,而不是硬编码。
而且我希望代码代替$comb = array('ID' => $arrs['ID'], 'Code' => $arrs['Code'],'Date' => $arrs['Date'],'Amount' => '');
自动将所有其他字段添加到ID匹配的第一个数组中。
我该如何实现?
答案 0 :(得分:2)
首先使用ID作为密钥:
$arr1 = array_column($arr1, null, "ID");
$arr2 = array_column($arr2, null, "ID");
然后对键进行排序(以解决原始索引不同的问题:
ksort($arr1);
ksort($arr2);
然后将array_map
用作:
$res = array_map('array_merge', $arr1, $arr2);
最后使用array_values
忽略ID键。
如果您还有另一个包含ID字段的数组,则可以对它们使用相同的逻辑-注意array_map
可以得到2个以上的输入数组...
参考:array_column,array_map,array_merge,ksort
实时示例:3v4l
已编辑:
使用模板来解决元素缺失的问题:
$keys = array_merge(array_keys($a[0]), array_keys($b[0]));
$template = array_combine($keys, array_fill(0, count($keys), null)); // create array of null for all keys
$a = array_column($a, null, "ID");
$b = array_column($b, null, "ID");
ksort($a);
ksort($b);
$res = array_map(function ($e1, $e2) use ($template){
if ($e1 && $e2) return array_merge($e1, $e2); // if exist merge
$e = $e1 ? $e1 : $e2; //get the exist element
return array_replace ($template, $e); // add it
}, $a, $b);
请注意,此解决方案仅对2个数组有效-可以概括,但我留给您
实时示例:3v4l
答案 1 :(得分:2)
除ID
外,使其完全动态的最简单解决方案,请执行以下操作:
$arr2 = array_column($array2, "ID");
$finalArray = array();
foreach($array1 as $arr){
$key = array_search($arr['ID'], $arr2);
if($key ===false){
$key = array_search(0, $arr2);
}
unset($array2[$key]['ID']);
$finalArray[] = array_merge($arr,$array2[$key]);
}
print_r($finalArray);
答案 2 :(得分:1)
我调整您的代码以执行所需的操作,这是为我工作的完整代码:
<?php
$arr=Array(
Array("ID" => 101, "Code" => 1075, "Date" => "2012-03-03 17:13:12.433"),
Array("ID" => 103, "Code" => 175, "Date" => "2013-03-03 17:13:12.433"),
Array("ID" => 109, "Code" => 178, "Date" => "2014-03-03 17:13:12.433")
);
$arr4 = Array(
Array("ID" => 101, "Amount" => 1234),
Array("ID" => 103, "Amount" => 1342),
Array("ID" => 0, "Amount" => 0)
);
$combined = array();
foreach ($arr as $i => $arrs) {
$combined['ID'][$i] = $arrs['ID'];
$combined['Code'][$i] = $arrs['Code'];
$combined['Date'][$i] = $arrs['Date'];
foreach ($arr4 as $arr2) {
if ($arr2['ID'] == $arrs['ID']) {
$combined['Amount'][$i] = $arr2['Amount'];
break;
}
}
if (!isset($combined['Amount'][$i])) {
$combined['Amount'][] = 0;
}
}
echo print_r($combined);
?>
如果出于各种原因需要进一步操作,建议您阅读有关array_keys
和array_values
方法的信息,这非常有帮助。
答案 3 :(得分:1)
$firstArray = [
[
'ID' => 101,
'Code' => 1075,
'Date' => '2012-03-03 17:13:12.433',
],
[
'ID' => 103,
'Code' => 175,
'Date' => '2012-09-05 20:30:02.217',
],
[
'ID' => 109,
'Code' => 178,
'Date' => '2012-07-05 20:30:02.217',
],
];
$secondArray = [
[
'ID' => 101,
'Amount' => 1234,
],
[
'ID' => 103,
'Amount' => 1342,
],
[
'ID' => 0,
'Amount' => 0,
],
];
class DTO implements \Serializable
{
/** @var int */
private $id;
/** @var int */
private $code;
/** @var string */
private $date;
/** @var int */
private $amount = 0;
/**
* {@inheritDoc}
*/
public function serialize()
{
return [
'ID' => $this->id,
'Code' => $this->code,
'Date' => $this->date,
'Amount' => $this->amount,
];
}
/**
* {@inheritDoc}
*
* @param array $serialized
*/
public function unserialize($serialized): self
{
$this->id = $serialized['ID'];
$this->code = $serialized['Code'];
$this->date = $serialized['Date'];
$this->amount = $serialized['Amount'] ?? 0;
return $this;
}
}
$thirdArray = [];
foreach ($secondArray as $item) {
$id = $item['ID'];
unset($item['ID']);
$thirdArray[$id] = $item;
}
$thirdArrayKeys = array_keys($thirdArray);
foreach ($firstArray as &$item) {
$id = $item['ID'];
$dto = new DTO();
$dto->unserialize($item);
if (in_array($id, $thirdArrayKeys)) {
$dto = $dto->unserialize(array_merge($item, $thirdArray[$id]));
}
$item = $dto->serialize();
}
http://sandbox.onlinephpfunctions.com/code/ee72a1c89782f4eef25a1143816f237ca6af129c