[英]Group multidimentional array with 3 index PHP
I am not sure if I can explain this correctly but i will try, 我不确定我能否正确解释这一点,但我会尽力而为,
I have a multidimensional array which looks like the array below. 我有一个多维数组,看起来像下面的数组。 Notice changes in GROUPINDEX , ELOCATRIND and UNITINDEX .
注意GROUPINDEX , ELOCATRIND和UNITINDEX中的更改 。 I tried a lot of looping, merge and filtering but couldn't able to achieve the desired result.
我尝试了很多循环,合并和过滤,但无法获得所需的结果。
Array
(
[0] => Array
(
[GROUPINDEX] => 1
[GROUPDESC] => Grading Parameters
[UNITINDEX] => 1
[ELOCATRIND] => 1
[ELOCATRDES] => Grading Date
[ELOCATRVAL] => 123
[CODEDESC] =>
)
[1] => Array
(
[GROUPINDEX] => 1
[GROUPDESC] => Grading Parameters
[UNITINDEX] => 2
[ELOCATRIND] => 1
[ELOCATRDES] => Grading Decider
[ELOCATRVAL] => abc
[CODEDESC] =>
)
[2] => Array
(
[GROUPINDEX] => 1
[GROUPDESC] => Grading Parameters
[UNITINDEX] => 5
[ELOCATRIND] => 1
[ELOCATRDES] =>
[ELOCATRVAL] => test-DE
[CODEDESC] =>
)
[3] => Array
(
[GROUPINDEX] => 1
[GROUPDESC] => Grading Parameters
[UNITINDEX] => 1
[ELOCATRIND] => 2
[ELOCATRDES] => Grading Date
[ELOCATRVAL] => 123-2
[CODEDESC] =>
)
[4] => Array
(
[GROUPINDEX] => 1
[GROUPDESC] => Grading Parameters
[UNITINDEX] => 2
[ELOCATRIND] => 2
[ELOCATRDES] => Grading Decider
[ELOCATRVAL] => abc-2
[CODEDESC] =>
)
[5] => Array
(
[GROUPINDEX] => 2
[GROUPDESC] => Genre Codes
[UNITINDEX] => 1
[ELOCATRIND] => 1
[ELOCATRDES] => Grading Date
[ELOCATRVAL] => 2017-02-01
[CODEDESC] =>
)
[6] => Array
(
[GROUPINDEX] => 2
[GROUPDESC] => Genre Codes
[UNITINDEX] => 2
[ELOCATRIND] => 1
[ELOCATRDES] => Grading Decider
[ELOCATRVAL] => NGR
[CODEDESC] =>
)
)
I need to group them in hierarchical order according to the above mentioned indexes. 我需要根据上述索引按层次结构将它们分组。 the final result should look like this:
最终结果应如下所示:
Array
(
[0] => Array
(
[GROUPINDEX] => 1
[GROUPDESC] => Grading Parameters
[UNITINDEX] => 1
[ELOCATRIND] => 1, 2
[ELOCATRDES] => Grading Date:123 | Grading Date : 123-2
)
[1] => Array
(
[GROUPINDEX] => 1
[GROUPDESC] => Grading Parameters
[UNITINDEX] => 2
[ELOCATRIND] => 1, 2
[ELOCATRDES] => Grading Decider:abc| Grading Decider:abc-2
)
[2] => Array
(
[GROUPINDEX] => 1
[GROUPDESC] => Grading Parameters
[UNITINDEX] => 5
[ELOCATRIND] => 1
[ELOCATRDES] =>
[ELOCATRVAL] => test-DE
[CODEDESC] =>
)
[5] => Array
(
[GROUPINDEX] => 2
[GROUPDESC] => Genre Codes
[UNITINDEX] => 1
[ELOCATRIND] => 1
[ELOCATRDES] => Grading Date
[ELOCATRVAL] => 2017-02-01
[CODEDESC] =>
)
[6] => Array
(
[GROUPINDEX] => 2
[GROUPDESC] => Genre Codes
[UNITINDEX] => 2
[ELOCATRIND] => 1
[ELOCATRDES] => Grading Decider
[ELOCATRVAL] => NGR
[CODEDESC] =>
)
)
I tried following snippet after some sanitization but it didn't work, and now I am out of ideas. 经过一些消毒后,我尝试按照以下代码段进行操作,但是它没有用,现在我没有主意了。
$result1 = array_map(
function ($id) use ($Array) {
return array_map(function ($data) {
if (is_array($data)) return join(" | ", array_unique($data));
return $data;
}, array_reduce(
array_filter($Array, function ($item) use ($id) { return $id === $item['UNITINDEX']; }),
function ($result1, $set) { return $result1 = array_filter(array_merge_recursive($result1, $set)); }, [ ]
)
);
},
array_unique(array_column($Array, 'UNITINDEX'))
);
Any help would be great and really appreciated. 任何帮助将是巨大的,非常感谢。
You talk about 3 indexes, but you don't use them as indexes at all. 您谈论了3个索引,但根本没有将它们用作索引。 Let's use them;
让我们使用它们; how about having a result like this?
这样的结果怎么样?
First index is GROUPINDEX. 第一个索引是GROUPINDEX。
[1] => [
[GROUPDESC] => Grading Parameters
[UNITINDEX] => [
[1] => [
[ELOCATRIND] => 1, 2
[ELOCATRDES] => Grading Date: 123 | Grading Date : 123-2
]
[2] => [
[ELOCATRIND] => 1, 2
[ELOCATRDES] => Grading Decider: abc | Grading Decider: abc-2
]
[5] => [
[ELOCATRIND] => 1
[ELOCATRDES] =>
]
]
]
[2] => [
[GROUPDESC] => Genre Codes
[UNITINDEX] => [
[1] => [
[ELOCATRIND] => 1
[ELOCATRDES] => Grading Date: 2017-02-01
]
[2] => [
[ELOCATRIND] => 1
[ELOCATRDES] => Grading Decider: NGR
]
]
]
The function to get that: 得到的功能:
<?php
function parseArr($arr) {
$return = [];
foreach($arr as $item) {
// Check if GROUPINDEX exists
if(!isset($return[$item['GROUPINDEX']]) {
$return[$item['GROUPINDEX']] = [
'GROUPDESC' => $item['GROUPDESC'],
'UNITINDEX' => []
];
}
// Check if UNITINDEX exists in this GROUPINDEX
if(!isset($return[$item['GROUPINDEX']]['UNITINDEX'][$item['UNITINDEX']])) {
// Create UNITINDEX array
$return[$item['GROUPINDEX']]['UNITINDEX'][$item['UNITINDEX']] = [
'ELOCATRIND' => $item['ELOCATRIND'],
'ELOCATRDES' => $item['ELOCATRDES'] . ': ' . $index['ELOCATRVAL']
];
} else {
// Update UNITINDEX array, just concat to previous values
$return[$item['GROUPINDEX']]['UNITINDEX'][$item['UNITINDEX']]['ELOCATRIND'] .= ', ' . $item['ELOCATRIND'];
$return[$item['GROUPINDEX']]['UNITINDEX'][$item['UNITINDEX']]['ELOCATRDES'] .= ' | ' . $item['ELOCATRDES'] . ': ' . $index['ELOCATRVAL'];
}
}
return $return;
}
This should give you a start. 这应该给您一个开始。
<?php
$items = [
[
'GROUPINDEX' => 1,
'GROUPDESC' => 'Grading Parameters',
'UNITINDEX' => 1,
'ELOCATRIND' => 1,
'ELOCATRDES' => 'Grading Date',
'ELOCATRVAL' => '123',
'CODEDESC' => null
], [
'GROUPINDEX' => 1,
'GROUPDESC' => 'Grading Parameters',
'UNITINDEX' => 2,
'ELOCATRIND' => 1,
'ELOCATRDES' => 'Grading Decider',
'ELOCATRVAL' => 'abc',
'CODEDESC' => null
], [
'GROUPINDEX' => 1,
'GROUPDESC' => 'Grading Parameters',
'UNITINDEX' => 5,
'ELOCATRIND' => 1,
'ELOCATRDES' => null,
'ELOCATRVAL' => 'test-DE',
'CODEDESC' => null
], [
'GROUPINDEX' => 1,
'GROUPDESC' => 'Grading Parameters',
'UNITINDEX' => 1,
'ELOCATRIND' => 2,
'ELOCATRDES' => 'Grading Date',
'ELOCATRVAL' => '123-2',
'CODEDESC' => null
], [
'GROUPINDEX' => 1,
'GROUPDESC' => 'Grading Parameters',
'UNITINDEX' => 2,
'ELOCATRIND' => 2,
'ELOCATRDES' => 'Grading Decider',
'ELOCATRVAL' => 'abc-2',
'CODEDESC' => null
], [
'GROUPINDEX' => 2,
'GROUPDESC' => 'Genre Codes',
'UNITINDEX' => 1,
'ELOCATRIND' => 1,
'ELOCATRDES' => 'Grading Date',
'ELOCATRVAL' => '2017-02-01',
'CODEDESC' => null
], [
'GROUPINDEX' => 2,
'GROUPDESC' => 'Genre Codes',
'UNITINDEX' => 2,
'ELOCATRIND' => 1,
'ELOCATRDES' => 'Grading Decider',
'ELOCATRVAL' => 'NGR',
'CODEDESC' => null
]
];
// let create's a dictionary (associative array) keyed on the GROUPINDEX|UNITINDEX
$dict = [];
foreach ($items as $item) {
$key = $item['GROUPINDEX'] . '|' . $item['UNITINDEX'];
// check if key does not exist in the dictionary to create a new entry
if (!isset($dict[$key])) {
$dict[$key] = [
'GROUPINDEX' => $item['GROUPINDEX'],
'GROUPDESC' => $item['GROUPDESC'],
'UNITINDEX' => $item['UNITINDEX'],
// for convenience, we'll use arrays here
'ELOCATRIND' => [],
'ELOCATRDES' => []
];
}
// add item to dictionary's entry
$dict[$key]['ELOCATRIND'][] = $item['ELOCATRIND'];
// @TODO: ADD SOME CONDITIONAL LOGIC HERE
$dict[$key]['ELOCATRDES'][] = $item['ELOCATRDES'] . ':' . $item['ELOCATRVAL'];
}
// let's clean up the dictionary now
foreach ($dict as $key => $item) {
$dict[$key]['ELOCATRIND'] = implode(', ', $item['ELOCATRIND']);
$dict[$key]['ELOCATRDES'] = implode(' | ', $item['ELOCATRDES']);
}
// sort dictionary by key
ksort($dict);
// remove keys
$dict = array_values($dict);
echo '<pre>' . print_r($dict, true) . '</pre>';
?>
It will output 它将输出
Array
(
[0] => Array
(
[GROUPINDEX] => 1
[GROUPDESC] => Grading Parameters
[UNITINDEX] => 1
[ELOCATRIND] => 1, 2
[ELOCATRDES] => Grading Date:123 | Grading Date:123-2
)
[1] => Array
(
[GROUPINDEX] => 1
[GROUPDESC] => Grading Parameters
[UNITINDEX] => 2
[ELOCATRIND] => 1, 2
[ELOCATRDES] => Grading Decider:abc | Grading Decider:abc-2
)
[2] => Array
(
[GROUPINDEX] => 1
[GROUPDESC] => Grading Parameters
[UNITINDEX] => 5
[ELOCATRIND] => 1
[ELOCATRDES] => :test-DE
)
[3] => Array
(
[GROUPINDEX] => 2
[GROUPDESC] => Genre Codes
[UNITINDEX] => 1
[ELOCATRIND] => 1
[ELOCATRDES] => Grading Date:2017-02-01
)
[4] => Array
(
[GROUPINDEX] => 2
[GROUPDESC] => Genre Codes
[UNITINDEX] => 2
[ELOCATRIND] => 1
[ELOCATRDES] => Grading Decider:NGR
)
)
You'll notice the last three are not the same as your desired result. 您会注意到最后三个与您期望的结果不同。 You would have to add the logic where it says
@TODO
in comments (because I don't know). 您必须在注释
@TODO
表示的地方添加逻辑(因为我不知道)。
Your code attempts were very close. 您的代码尝试非常接近。 array_map() would be a good choice if the desired had one value corresponding to each element in the original array.
如果所需数组具有一个与原始数组中每个元素相对应的值,则array_map()将是一个不错的选择。 However, because the desired output doesn't have one element for each element in the original array, use array_reduce() with array_filter() inside instead of array_map() .
但是,由于所需的输出对于原始数组中的每个元素都没有一个元素,因此请在array_reduce()中使用array_filter()而不是array_map() 。 That way, when using array_reduce(), the code can conditionally add the current item to the result array or update the existing item that has the matching UNITINDEX and GROUPINDEX values.
这样,当使用array_reduce()时,代码可以有条件地将当前项目添加到结果数组中,或更新具有匹配UNITINDEX和GROUPINDEX值的现有项目。
In the code snippet below, also notice that array_keys() is used to get the index of the first found item (if it exists), and array_key_exists() is used to check if the key ELOCATRVAL exists on the found item. 在下面的代码片段中,还请注意, array_keys()用于获取找到的第一个项目的索引(如果存在),而array_key_exists()用于检查找到的项目上是否存在键ELOCATRVAL 。 In that case, the value is appended to the ELOCATRDES key and the existing value is unset (using unset() ).
在这种情况下,该值将附加到ELOCATRDES键,并且未设置现有值(使用unset() )。
$result1 = array_reduce($Array, function($result, $currentItem) {
$existingItems = array_filter($result, function ($item) use ($currentItem) {
return $currentItem['UNITINDEX'] === $item['UNITINDEX'] && $currentItem['GROUPINDEX'] === $item['GROUPINDEX'];
});
if (count($existingItems)) {//matching item found
$index = array_keys($existingItems)[0];
if (array_key_exists('ELOCATRVAL', $result[$index])) {
$result[$index]['ELOCATRDES'] .= ':'.$result[$index]['ELOCATRVAL'];
unset($result[$index]['ELOCATRVAL']);
}
$result[$index]['ELOCATRIND'] .= ', '.$currentItem['ELOCATRIND'];
$result[$index]['ELOCATRDES'] .= '| '.$currentItem['ELOCATRDES'].':'.$currentItem['ELOCATRVAL'];
}
else { //no match - push the item into the array
$result[] = $currentItem;
}
return $result; //return cumulative array after iterating over each item
}, []); //pass empty array as initial value of $result
See a demonstration of this in this PHP playground example . 在此PHP游乐场示例中查看此演示。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.