我发现自己经常在寻找PHP中各种数组排列问题的解决方案时遇到困难,这些问题超出了我之前实现的解决方案。
目前,我从这个数组开始:
$tags = array(
array('tag_id' => 1, 'tag_name' => 'Hello', 'album_id => 1'),
array('tag_id' => 1, 'tag_name' => 'Hello', 'album_id => 2'),
array('tag_id' => 2, 'tag_name' => 'World', 'album_id => 1'),
array('tag_id' => 2, 'tag_name' => 'World', 'album_id => 2'),
array('tag_id' => 3, 'tag_name' => 'Again', 'album_id => 3')
);
并希望如此组织:
$organized_tags = array(
array('tag_id' => 1, 'tag_name' => 'Hello', 'album_ids' => array(1,2)),
array('tag_id' => 2, 'tag_name' => 'World', 'album_ids' => array(1,2)),
array('tag_id' => 3, 'tag_name' => 'Again', 'album_ids' => array(3))
);
a)解决此类问题的最佳策略是什么? b)如何考虑解决未来出现的通用阵列问题?
答案 0 :(得分:0)
超级幼稚的方法:
$result = [];
foreach ($array as $item) {
foreach ($result as $resultItem) {
if ($item['tag_id'] == $resultItem['tag_id']) {
$resultItem['album_ids'][] = $item['album_id'];
continue 2;
}
}
$result = $item + ['album_ids' => (array)$item['album_id']];
}
即,您只需遍历数组,并在每次迭代中遍历结果数组,以查看项目适合的位置。这非常简单。
通常,更优化的解决方案是通过您尝试分组的属性对结果数组进行索引:
$result = [];
foreach ($array as $item) {
if (!isset($result[$item['album_id']])) {
$result[$item['album_id']] = $item + ['album_ids' => (array)$item['album_id']];
} else {
$result[$item['album_id']]['album_ids'][] = $item['album_id']
}
}
答案 1 :(得分:0)
我可能会从CakePHP的书中拿出一片叶子,将模型数据表示为数组。
有了这个,你就会有一个Tag模型和一个Album模型。从数据给出,Tag模型看起来像
['Tag' => ['tag_id' => 1, 'tag_name' => 'Hello']]
目前,专辑只有id
['Album' => ['album_id' => 1']]
代表有组织的结构:
[
0 => [
'Tag' => ['tag_id' => 1, 'tag_name' => 'Hello'],
'Album' => [
0 => ['album_id' => 1],
1 => ['album_id' => 2]
],
1 => [
'Tag' => ['tag_id' => 2, 'tag_name' => 'World'],
'Album' => [
0 => ['album_id' => 1],
1 => ['album_id' => 2]
],
2 => [
'Tag' => ['tag_id' => 3, 'tag_name' => 'Again'],
'Album' => [
0 => ['album_id' => 3]
]
]
但是,这不是你要求的。
要将$tags
更改为$organized_tags
,我会创建一个Tag
模型类,它采用$tags
结构,遍历它,并构建第二个结构。
public function toOrganizedTags($tags) {
$organizedTags = [];
foreach ($tags as $tag) {
if (!isset($organizedTags[$tag['tag_id']]) {
// make sure an entry exists. We assume that tag_name does not change between similar tag_id entries.
$organizedTags[$tag['tag_id']] = [
'tag_id' => $tag['tag_id'],
'tag_name' => $tag['tag_name'],
'album_ids' => []
];
}
$organizedTags[$tag['tag_id']]['album_ids'][] = $tag['album_id'];
}
// use array_values to strip the indexed keys
return array_values($organizedTags);
}