将数组元素组合成单个元素,直到某一点


Combining array elements into a single one, up to a certain point

我正在用PHP构建一个生活流式的博客。它从我的MySQL数据库中获取我的博客文章,以及我的推文和Last.fm scrobbles。

到目前为止还不错,但我想将多个后续scrobble合并为一个。不过,一切都需要按时间顺序排列,因此,如果一篇博客文章或一条推文打破了一系列的scrobbles,那么链的第二部分就不能与第一部分结合在一起。

Array
(
    [0] => Array
        (
            [contents] => Disturbed
            [type] => scrobble
            [published] => 1327695674
        )
    [1] => Array
        (
            [contents] => Amon Amarth
            [type] => scrobble
            [published] => 1327695461
        )
    [2] => Array
        (
            [contents] => Apocalyptica
            [type] => scrobble
            [published] => 1327693094
        )
    [3] => Array
        (
            [contents] => This is a tweet. Really.
            [type] => tweet
            [published] => 1327692794
        )
    [4] => Array
        (
            [contents] => Dead by Sunrise
            [type] => scrobble
            [published] => 1327692578
        )
)

因此,由于[3]是一个tweet,scrobbles[0]-[2]应该组合成一个元素。时间戳[published]应设置为组合元素中的最新元素,并且[contents]字符串将使用逗号组合在一起。但[4]不能成为组合的一部分,因为这会打破事物的时间顺序。

如果你仍然和我在一起:我想我可以使用大量的迭代和条件等,但我不确定如何在考虑性能的情况下处理事情。我可以使用任何特定于数组的函数吗?

$posts = array( /* data here: posts, tweets... */ );
$last_k = null;
foreach( $posts as $k => $v )
{
    if( ( null !== $last_k ) && ( $posts[ $last_k ][ 'type' ] == $v[ 'type' ] ) )
    {
        $posts[ $last_k ][ 'contents' ][] = $v[ 'contents' ];
        $posts[ $last_k ][ 'published' ] = max( $posts[ $last_k ][ 'published' ], $v[ 'published' ] );
        unset( $posts[ $k ] );
        continue;
    }
    $posts[ $k ][ 'contents' ] = (array)$v[ 'contents' ];
    $last_k = $k;
}

因为"contents"索引现在是数组,所以您必须对输出使用联接函数。类似:

foreach( $posts as $v )
{
    echo '<div>', $v[ 'type' ], '</div>';
    echo '<div>', $v[ 'published' ], '</div>';
    echo '<div>', join( '</div><div>', $v[ 'contents' ] ), '</div>';
}

我会尝试一个经典的switch语句:

$lastType = "";
$count = 0;
foreach($arrays as $array) {
    switch($array["type"]) {
        case "scrobble":
            if($lastType == "scrobble")
              $count++;
            else {
                $count = 1;
                $lastType = "scrobble";
            }
            break;
        case "tweet":
            // same as above
            break;
    }
}

这就完成了任务:

$last_type = '';
$out = array();
foreach ($events as $row){
    if ($last_type == 'scrobble' && $row['type'] == 'scrobble'){
        array_pop($out);
    }
    $out[] = $row;
    $last_type = $row['type'];
}

循环遍历每个条目,将它们添加到输出数组中。当我们遇到一个scrobble,其中前一个条目也是scrobble时,请从输出列表中删除前一个条目的条目。