我正在寻找php
中的解决方案,如此问题的接受答案所述:
请在下面找到代码:
<?php
$items = array(
'tableData' => array
(
array
(
'booking_name' => 'abc/xyz/123',
'pdg' => 'assure',
'user_area' => 'es st1',
'release' => 'oss72',
'start_date' => '2017-06-20 00:00:00',
'end_date' => '2017-06-23 00:00:00',
'asset_info' => array
(
array
(
'status' => 10,
'manufacturer' => 'Oracle',
'model' => 'HP BL460C GEN8',
'hardware_color' => '#0066b3',
),
array
(
'status' => 11,
'manufacturer' => 'HP',
'model' => 'HP BL460C GEN81',
'hardware_color' => '#0066b3',
)
),
'full_name' => 'Valay Desai',
'email_address' => 'valay@xyz.com',
),
array
(
'booking_name' => 'abc/xyz/123',
'pdg' => 'enm',
'user_area' => 'es st',
'release' => 'oss72',
'start_date' => '2017-06-20 00:00:00',
'end_date' => '2017-06-23 00:00:00',
'asset_info' => array
(
array
(
'status' => 10,
'manufacturer' => 'HP',
'model' => 'HP BL460C GEN8',
'hardware_color' => '#0066b3',
)
),
'full_name' => 'Valay Desai',
'email_address' => 'valay@xyz.com',
)
)
);
function getParentStackComplete($child, $stack) {
$return = array();
foreach ($stack as $k => $v) {
if (is_array($v)) {
// If the current element of the array is an array, recurse it
// and capture the return stack
$stack = getParentStackComplete($child, $v);
// If the return stack is an array, add it to the return
if (is_array($stack) && !empty($stack)) {
$return[] = $v;
}
} else {
// Since we are not on an array, compare directly
if(strpos($v, $child) !== false){
// And if we match, stack it and return it
$return[] = $v;
}
}
}
// Return the stack
return empty($return) ? false: $return;
}
echo "<pre>";
print_r(getParentStackComplete('Oracle', $items['tableData']));
echo "</pre>";
?>
此代码工作正常。我发现函数getParentStackComplete
在线,修改它以返回整个匹配元素。它以递归方式搜索数组并返回匹配项。
例如,如代码中所示,如果我搜索字符串&#39; Oracle&#39;,它应该返回一个数组,其中一个项目在asset_info
中只有一个子项(匹配元素) 。我正在寻找的输出是:
Array
(
[0] => Array
(
[booking_name] => abc/xyz/123
[pdg] => assure
[user_area] => es st1
[release] => oss72
[start_date] => 2017-06-20 00:00:00
[end_date] => 2017-06-23 00:00:00
[asset_info] => Array
(
[0] => Array
(
[status] => 10
[manufacturer] => Oracle
[model] => HP BL460C GEN8
[hardware_color] => #0066b3
)
)
[full_name] => Valay Desai
[email_address] => valay@xyz.com
)
)
如果我搜索字符串HP BL460C GEN8
,它应该返回如下:
Array
(
[0] => Array
(
[booking_name] => abc/xyz/123
[pdg] => assure
[user_area] => es st1
[release] => oss72
[start_date] => 2017-06-20 00:00:00
[end_date] => 2017-06-23 00:00:00
[asset_info] => Array
(
[0] => Array
(
[status] => 10
[manufacturer] => Oracle
[model] => HP BL460C GEN8
[hardware_color] => #0066b3
)
)
[full_name] => Valay Desai
[email_address] => valay@xyz.com
)
[1] => Array
(
'booking_name' => 'abc/xyz/123',
'pdg' => 'enm',
'user_area' => 'es st',
'release' => 'oss72',
'start_date' => '2017-06-20 00:00:00',
'end_date' => '2017-06-23 00:00:00',
'asset_info' => array
(
array
(
'status' => 10,
'manufacturer' => 'HP',
'model' => 'HP BL460C GEN8',
'hardware_color' => '#0066b3',
)
),
'full_name' => 'Valay Desai',
'email_address' => 'valay@xyz.com'
)
)
如何在嵌套数组搜索中将匹配的子项与父项一起返回?
答案 0 :(得分:3)
试试这段代码。
function getParentStackComplete( $search, $stack ){
$results = array();
foreach( $stack as $item ){
if( is_array( $item ) ){
if( array_filter($item, function($var) use ($search) { return ( !is_array( $var ) )? stristr( $var, $search ): false; } ) ){
//echo 'test';
$results[] = $item;
continue;
}else if( array_key_exists('asset_info', $item) ){
$find_assets = array();
foreach( $item['asset_info'] as $k=>$v ){
//echo 'abc ';
if( is_array( $v ) && array_filter($v, function($var) use ($search) { return stristr($var, $search); }) ){
$find_assets[] = $v;
}
}
if( count( $find_assets ) ){
$temp = $item;
$temp['asset_info'] = $find_assets;
$results[] = $temp;
}
}
}
}
return $results;
}
答案 1 :(得分:2)
要仅对叶子节点进行深度搜索,这是通过RecursiveIterator递归迭代直接进行的,其RecursiveIteratorIterator通过RecursiveArrayIterator处理仅叶子遍历。
要在此处显示示例数据的小搜索示例:
$iterator = new RecursiveArrayIterator($items['tableData']); # 1.
$leafs = new RecursiveIteratorIterator($iterator); # 2.
$search = new RegexIterator($leafs, sprintf('~^%s$~', preg_quote('HP BL460C GEN8', '~'))); # 3.
foreach ($search as $value) { # 4.
var_dump($value);
}
确实
foreach
搜索并输出示范值。并输出:
string(14) "HP BL460C GEN8"
string(14) "HP BL460C GEN8"
搜索有效地设置在三行代码中。
并非全部,因为在foreach
内部我们仍然拥有装饰迭代的上下文,您不仅可以访问当前值,还可以访问三个级别, parent 你想回来:
foreach ($search as $key => $value) {
$parentLevel = 0; # or for relative access: $leafs->getDepth() - 3
$parent = $leafs->getSubIterator($parentLevel)->current();
var_dump($parent);
}
这将输出与搜索匹配的所有父对象。
可能已经回答了你的问题,让我们完整展示一下这个例子:
$search = function (array $array, string $term) {
$iterator = new RecursiveArrayIterator($array);
$leafs = new RecursiveIteratorIterator($iterator);
$search = new RegexIterator($leafs, sprintf('~^%s$~', preg_quote($term, '~')));
foreach ($search as $value) {
$parent = $leafs->getSubIterator(0)->current();
yield $parent;
}
};
$matches = $search($items['tableData'], 'HP BL460C GEN8');
foreach ($matches as $index => $match) {
echo $index + 1, ': ';
print_r($match);
}
它的输出:
1: Array
(
[booking_name] => abc/xyz/123
[pdg] => assure
[user_area] => es st1
[release] => oss72
[start_date] => 2017-06-20 00:00:00
[end_date] => 2017-06-23 00:00:00
[asset_info] => Array
(
[0] => Array
(
[status] => 10
[manufacturer] => Oracle
[model] => HP BL460C GEN8
[hardware_color] => #0066b3
)
[1] => Array
(
[status] => 11
[manufacturer] => HP
[model] => HP BL460C GEN81
[hardware_color] => #0066b3
)
)
[full_name] => Valay Desai
[email_address] => valay@xyz.com
)
2: Array
(
[booking_name] => abc/xyz/123
[pdg] => enm
[user_area] => es st
[release] => oss72
[start_date] => 2017-06-20 00:00:00
[end_date] => 2017-06-23 00:00:00
[asset_info] => Array
(
[0] => Array
(
[status] => 10
[manufacturer] => HP
[model] => HP BL460C GEN8
[hardware_color] => #0066b3
)
)
[full_name] => Valay Desai
[email_address] => valay@xyz.com
)
但是,如果您可能希望将父asset_info
数组减少为仅包含这些匹配而不仅仅包含匹配的所有父项,该怎么办?如果是这样,则需要创建一个结果数组,该数组仅包含匹配的asset_info
条目中的那些条目。这需要跟踪匹配的父母,以便匹配asset_info
可以添加到他们的结果中。
因为这需要处理同一父级的所有匹配资产,然后仅为这些父级提供这些匹配。因此匹配将在其父级中进行分组,因此这是一种聚合函数,因此需要管理更多内容,因为如果父级已经具有所有匹配项,它需要跟踪:
$search = function (array $array, string $term) {
$iterator = new RecursiveArrayIterator($array);
$leafs = new RecursiveIteratorIterator($iterator);
/* @var $search RecursiveIteratorIterator|RegexIterator - $search is a decorator of that type */
$search = new RegexIterator($leafs, sprintf('~^%s$~', preg_quote($term, '~')));
# initialize
$match = $lastId = null;
foreach ($search as $key => $value) {
$parentId = $search->getSubIterator(0)->key();
if ($lastId !== $parentId && $match) {
yield $match;
$match = null;
}
$lastId = $parentId;
if (empty($match)) {
# set match w/o asset_info as yet not matched
$match = $search->getSubIterator(0)->current();
$match['asset_info'] = [];
}
# add matched asset into the matched asset_info
$match['asset_info'][] = $search->getSubIterator(2)->current();
}
$match && yield $match;
};
$matches = $search($items['tableData'], 'HP BL460C GEN8');
foreach ($matches as $index => $match) {
echo $index + 1, ': ';
print_r($match);
}
输出在您的情况下给出:
1: Array
(
[booking_name] => abc/xyz/123
[pdg] => assure
[user_area] => es st1
[release] => oss72
[start_date] => 2017-06-20 00:00:00
[end_date] => 2017-06-23 00:00:00
[asset_info] => Array
(
[0] => Array
(
[status] => 10
[manufacturer] => Oracle
[model] => HP BL460C GEN8
[hardware_color] => #0066b3
)
)
[full_name] => Valay Desai
[email_address] => valay@xyz.com
)
2: Array
(
[booking_name] => abc/xyz/123
[pdg] => enm
[user_area] => es st
[release] => oss72
[start_date] => 2017-06-20 00:00:00
[end_date] => 2017-06-23 00:00:00
[asset_info] => Array
(
[0] => Array
(
[status] => 10
[manufacturer] => HP
[model] => HP BL460C GEN8
[hardware_color] => #0066b3
)
)
[full_name] => Valay Desai
[email_address] => valay@xyz.com
)
注意第一场比赛中asset_info
的参赛人数的微妙差异,即一个而不是之前的两个。
答案 2 :(得分:1)
<?php
$items = array(
'tableData' => array
(
array
(
'booking_name' => 'abc/xyz/123',
'pdg' => 'assure',
'user_area' => 'es st1',
'release' => 'oss72',
'start_date' => '2017-06-20 00:00:00',
'end_date' => '2017-06-23 00:00:00',
'asset_info' => array
(
array
(
'status' => 10,
'manufacturer' => 'Oracle',
'model' => 'HP BL460C GEN8',
'hardware_color' => '#0066b3',
),
array
(
'status' => 11,
'manufacturer' => 'HP',
'model' => 'HP BL460C GEN81',
'hardware_color' => '#0066b3',
)
),
'full_name' => 'Valay Desai',
'email_address' => 'valay@xyz.com',
),
array
(
'booking_name' => 'abc/xyz/123',
'pdg' => 'enm',
'user_area' => 'es st',
'release' => 'oss72',
'start_date' => '2017-06-20 00:00:00',
'end_date' => '2017-06-23 00:00:00',
'asset_info' => array
(
array
(
'status' => 10,
'manufacturer' => 'HP',
'model' => 'HP BL460C GEN8',
'hardware_color' => '#0066b3',
)
),
'full_name' => 'Valay Desai',
'email_address' => 'valay@xyz.com',
)
)
);
function getParentStackComplete($child, $stack) {
$return = array();
$k=0;
foreach ($stack as $k => $v) {
if (is_array($v)) {
if (is_array($stack) && !empty($stack) && $k==0) {
unset($v['asset_info'][1]);
$return = $v;
}
} else {
if(strpos($v, $child) !== false){
$return[] = $v;
}
}
$k++;
}
return empty($return) ? false: $return;
}
echo "<pre>";
print_r(getParentStackComplete('Oracle', $items['tableData']));
echo "</pre>";
答案 3 :(得分:-1)
这应该可以解决问题。
function getParentStackComplete($search, $stack)
{
$results = [];
foreach ($stack as $i => $item) {
$results[] = $item;
$cache = $item['asset_info'];
$results[$i]['asset_info'] = [];
$found = false;
foreach ($cache as $asset) {
if (array_search($search, $asset) !== false) {
print('here' . "\n");
$found = true;
$results[$i]['asset_info'][] = $asset;
}
}
if (!$found) {
unset($results[$i]);
}
}
return $results;
}
修改:这假设您正在调用此getParentStackComplete('Oracle', $items['tableData'])