【问题标题】:Limit a for each loop in a tag cloud为标签云中的每个循环限制一个
【发布时间】:2011-04-14 16:08:01
【问题描述】:

我有以下标签云。

$rows = $db->loadObjectList();
foreach ($rows as $row)
{
$strAllTags .= $row->caption . ","; 
}

// Store frequency of words in an array
$freqData = array(); 

// Get individual words and build a frequency table
foreach( explode(",", $strAllTags) as $word )
{
// For each word found in the frequency table, increment its value by one
array_key_exists( trim($word), $freqData ) ? $freqData[ trim($word) ]++ : $freqData[ trim($word) ] = 0;
}


function getCloud( $data = array(), $minFontSize = 12, $maxFontSize = 32 )
{
$minimumCount = min( array_values( $data ) );
$maximumCount = max( array_values( $data ) );
$spread       = $maximumCount - $minimumCount;
$cloudHTML    = '';
$cloudTags    = array();

$spread = 55;

foreach( $data as $tag => $count )
{
            if ($count > 4)
            {
    $size = $minFontSize + ( $count - $minimumCount ) 
        * ( $maxFontSize - $minFontSize ) / $spread;
    $cloudTags[] = '[[a style="font-size: ' . floor( $size ) . 'px' 
    . '" class="tag_cloud" href="/home?func=search&searchfield=' . $tag 
    .  '"]]' 
    . htmlspecialchars( stripslashes( $tag ) ) . '[[/a]]';
           }
}

return join( "\n", $cloudTags ) . "\n";
}   
echo getCloud($freqData);
?>

效果很好,我只需要将其限制在前 20 个结果中,关于如何做到最好的任何想法?

谢谢,如果您需要查看其余代码,请告诉我。

【问题讨论】:

    标签: php foreach limit tag-cloud


    【解决方案1】:

    获取另一个计数器变量并在循环中递增并检查是否达到 20 打破循环

    使用数组切片

    $data = array_slice($data, 0, 20);
    
    foreach( $data as $tag => $count )
    {
    .....
    

    【讨论】:

    • @shakti 我想到了这一点,但那不是简单地返回 20 个没有特定顺序的结果吗?我需要 20 个标签成为整个标题数据库中最常用的标签,我编辑了原始帖子以显示前一部分代码,使其更清晰。
    • @Sherif:most used 你是什么人?你说的是数组排序吗?
    • @shakti 好吧,我尝试了您的解决方案,它只显示 10 个标签而不是 20 个,但如果我出于某种原因使用 ($data, 0, 40) 我得到 20 个。我只是没有确定它是否真的是前 20 个 - 最常用于网站上的用户标记他们的图片时,标签云应该只显示最常出现的 20 个标签,然后将这 20 个标签从 12 像素扩展到 32 像素
    • @Sherif:这是因为if ($count > 4)。将显示数组中大于 4 的值。
    • @shakti 我很确定有超过 20 个单词被使用超过 4 次。否则为什么它会与 ($data, 0, 40) 一起使用?再次抱歉,非常新。
    【解决方案2】:

    如果您的数组尚未排序,您可以使用arsort() 按最高结果对其进行排序。然后您可以使用array_slice() 创建一个仅包含前 20 个数组元素的新数组:

    arsort($data);
    $data = array_slice($data, 0, 20);
    

    arsort 表示“关联反向排序”。这只是意味着它作用于关联数组,维护它们的键,并按其值以“反向”(即从高到低)顺序对数组进行排序。

    array_slice 只是将现有数组“切片”。在此示例中,它表示“获取 $data 数组,并返回一个包含其 20 个值的新数组,从第一个值开始。

    为了解决您在 cmets 中提出的观点,当您希望它们是随机的时,导致标签也按大小顺序显示。抓取前 20 条记录后,您可以通过在数组上使用 shuffle 来完成此操作:

    arsort($data);
    $data = array_slice($data, 0, 20);
    shuffle($data);
    

    【讨论】:

    • 我将在哪里/如何在我的代码中添加它,抱歉我是个菜鸟!
    • 更好的方法是将你的方法和@Shakti 的方法结合起来。先排序,然后在 20 处休息。
    • @Sherif:我添加了一个简单的示例。请注意,我将函数从asort 更改为arsort,因为我在写原始答案时是个白痴。
    • @JohnP:这可能更多的是个人喜好。我真的不认为这两种方法之间有太大的性能差异,我认为使用array_splice 可能会更干净。
    • @AgentConundrum 我确实用 arsort 尝试了你的方法,它确实有效,但是现在我的标签云按从大到小的顺序显示,而之前不同的标签大小将是随机的。朋友建议我以后随机化,不知道该怎么做?
    猜你喜欢
    • 1970-01-01
    • 2021-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多