PHP中自定义数组功能的策略

时间:2014-06-26 05:18:36

标签: php arrays recursion

我发现自己经常在寻找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)如何考虑解决未来出现的通用阵列问题?

2 个答案:

答案 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);
}