基于值的动态计数

时间:2016-05-06 20:27:07

标签: php

所以,我有一个二维数组:

$fruits = array
  (
  array('fruit' => 'Apple', 'rating' => '2'),
  array('fruit' => 'Pear', 'rating' => '3'),
  array('fruit' => 'Peach', 'rating' => '2'),
  array('fruit' => 'Strawberry', 'rating' => '2')
  );

我需要明确的订单。因此,以上面的示例为例,我想显示一个table,其中包含三个col s - >水果,评级和排名。如果评级中存在任何相等性,那么我希望在第三列中具有可能等级的radio buttons。这就是我的意思:

enter image description here

到目前为止,我有下面的代码,它只能判断是否有另一种具有相同评级的水果,如果是,则显示1-4的无线电。这是一个非常粗鲁的解决方案。那么我怎样才能轻松地建立起来,考虑到评级可以是任何东西。对于例如2-2-3-3在这种情况下我需要收音机1-2,1-2和3-4,3-4。

PHP:

echo "<table><tr><td>fruit</td><td>rating</td><td>rank</td></tr>";
for($i = 0; $i < count($fruits); ++$i) {
    echo "<tr><td>".$fruits[$i]['fruit']."</td><td>".$fruits[$i]['rating']."</td><td>";    
    for($j = 0; $j < count($fruits); ++$j) {
        if($i != $j) {  
            if($fruits[$i]['rating'] == $fruits[$j]['rating']) {
                echo "<input type=\"radio\" name=\"".$fruits[$i]['fruit']."\" value=\"1\">1
                <input type=\"radio\" name=\"".$fruits[$i]['fruit']."\" value=\"2\">2
                <input type=\"radio\" name=\"".$fruits[$i]['fruit']."\" value=\"3\">3
                <input type=\"radio\" name=\"".$fruits[$i]['fruit']."\" value=\"4\">4"
                break;
            }
            else if ($j == 3)
            {
                echo "<b>".($i+1)."</b></td></tr>";
            }
        }
        else if ($j==3)
        {
            echo "<b>".($i+1)."</b></td></tr>";
        }
    }
}
echo "</table>";

基本上我需要对所有具有相同性的情况进行每次评级计数。

P.S。:数组已根据评分排序DESC,这就是($i+1)在我的代码中有效的原因。

3 个答案:

答案 0 :(得分:1)

由于您已经有预先排序的数组,因此您需要找到范围。

获得范围后,您可以输出该组行。

以下是一个例子:

echo "<table><tr><td>fruit</td><td>rating</td><td>rank</td></tr>";
$total = count($fruits);
for( $i=0; $i<$total; $i=$range_end+1) {
    $range_start = $i;
    while($i+1 < $total && $fruits[$i]['rating'] == $fruits[$i+1]['rating']) {
        $i++;
    }
    $range_end = $i;

    $range = array_slice($fruits, $range_start, $range_end-$range_start+1);
    foreach($range as $fruit) {
        echo "<tr>"
            ."<td>".$fruit['fruit']."</td>"
            ."<td>".$fruit['rating']."</td>"
            ."<td>";
        if( $range_start == $range_end) {
            echo $fruit['rating'];
        }
        else {
            for($j=$range_start; $j<=$range_end; $j++) {
                echo '<input type="radio" name="'.$fruit['fruit'].'" value="'.$j.'">'.$j;
            }
        }
        echo "</td>"
        ."</tr>";
    }
}
echo "</table>";

注意稍微不同寻常的for $i循环。这里发生的是我们从0开始循环,记录我们在$range_start的位置,然后前进直到下一个水果的评级不同。此时我们有$range_end,如果没有相同评级的水果,则可能与$range_start相同。然后我们从$fruits数组中提取范围并输出它。完成后,循环继续超出我们刚刚完成的范围结束的一个位置。

答案 1 :(得分:0)

以下是我的建议:

$fruits = array(
  array('fruit' => 'Apple', 'rating' => '2'),
  array('fruit' => 'Pear', 'rating' => '3'),
  array('fruit' => 'Peach', 'rating' => '2'),
  array('fruit' => 'Strawberry', 'rating' => '2')
);

// get unique ratings, in descending order
$ratings = array_unique(array_column($fruits, 'rating'));
sort($ratings);
$ratings = array_fill_keys(array_reverse($ratings), array());

// put fruits in their respective rating buckets:
foreach($fruits as $fruit) {
    $ratings[$fruit['rating']][] = $fruit['fruit'];
}

// Generate the HTML table
$html = "<table border=1><tr><th>fruit</th><th>rating</th><th>rank</th></tr>";
$rank = 1;
foreach($ratings as $rating => $fruits) {
    foreach($fruits as $fruit) {
        if (count($fruits) === 1) {
            $rankHtml = "<b>$rank</b>";
        } else {
            $rankHtml = "";
            for ($i = $rank; $i < $rank + count($fruits); $i++) {
                $rankHtml .= "<input type='radio' name='$fruit' value='$i'>$i";
            }
        }
        $html .= "<tr><td>$fruit</td><td>$rating</td><td>$rankHtml</td></tr>\n";
    }
    $rank += count($fruits);
}
$html .= "</table>";

echo $html;

如您所见,我喜欢将逻辑与输出分开。唯一的echo就在最后。

此方法的主要特征是中间结构,其中水果名称根据其共同评级被分组为单独的阵列。我认为这会产生更好的代码。

答案 2 :(得分:0)

看看usort()。这可以根据自定义函数重新排序数组(或克隆它)。

usort