首页 > 解决方案 > 需要一种更简洁的方法来打破 php 的平局

问题描述

我有一个有 4 个选项的民意调查,有时人们投票支持相同的事情,而选择最终会打成平手。我正在寻找打破这种联系的方法。

轮询变量总是不同的,下面只是它们如何产生的一个例子。我目前正在使用凌乱的 if 语句和随机化每个场景或一个 === 另一个的结果。

<?php

$choice1=4;
$choice2=4;
$choice3=2;
$choice4=4;

if ($choice1==$choice2) {
$a = ['$choice1','$choice2'];
$breaker = $a[mt_rand(0, count($a)-1)];
echo $breaker;

}elseif ($choice1==$choice3) {
$a = ['$choice1','$choice3'];
$breaker = $a[mt_rand(0, count($a)-1)];
echo $breaker;

}elseif ($choice1==$choice4) {
$a = ['$choice1','$choice4'];
$breaker = $a[mt_rand(0, count($a)-1)];
echo $breaker;

}elseif ($choice2==$choice1) {
$a = ['$choice2','$choice1'];
$breaker = $a[mt_rand(0, count($a)-1)];
echo $breaker;

//etc...
// This goes on and on also goes up to 3 way ties and 4 way ties.

这种方法看起来非常不优雅,而且随着越来越多的用户注册投票,投票数量也会增加,所以目前无法扩展,有什么建议吗?

标签: php

解决方案


这种方法使用具有两组排序的数组。

// As many choices as you would like
$choices = [
    ['id' => 1, 'name' => 'choice1', 'count' => 4],
    ['id' => 2, 'name' => 'choice2', 'count' => 4],
    ['id' => 3, 'name' => 'choice3', 'count' => 2],
    ['id' => 4, 'name' => 'choice4', 'count' => 4],
    ['id' => 5, 'name' => 'choice5', 'count' => 4],
    ['id' => 6, 'name' => 'choice6', 'count' => 4],
    ['id' => 7, 'name' => 'choice7', 'count' => 4],
    ['id' => 8, 'name' => 'choice8', 'count' => 6],
    ['id' => 9, 'name' => 'choice9', 'count' => 7],
    ['id' => 10, 'name' => 'choice10', 'count' => 4],
    ['id' => 11, 'name' => 'choice11', 'count' => 6],
    ['id' => 12, 'name' => 'choice12', 'count' => 6],
    ['id' => 13, 'name' => 'choice13', 'count' => 7],
    ['id' => 14, 'name' => 'choice14', 'count' => 3],
    ['id' => 15, 'name' => 'choice15', 'count' => 4],
];

// First, sort by count
usort($choices, function($a, $b) {
    if ( $a['count'] < $b['count'] ) return -1; // a < b
    elseif ( $a['count'] > $b['count'] ) return 1; // a > b
    return 0;
});
// Now, all are sorted by count.
// Walk through and deal with items that have the same count.
$buf = []; // A temp buffer to keep all items with a certain count
$prevCcount = null;
$output = [];
foreach($choices as $choice) {
    $count = $choice['count'];
    echo sprintf('id %d  count %d', $choice['id'], $choice['count']) . "\n";
    if ( $prevCount != $count ) {
        // Possible new group of items with the same count
        // Does the buffer have more than 1. If so, randomize.
        if ( count($buf) > 1 ) {
            echo "Shuffling " . count($buf) . "items\n";
            $shuffled = shuffle($buf);
            if ( ! $shuffled ) {
                throw new Exception('Failed to shuffle');
            }
        }
        if ( count($buf) > 0 ) {
            $output = array_merge($output, $buf);
            $buf = [];
        }
    }
    $prevCount = $count; // Keep track of count of previous item
    $buf[] = $choice; // add current item to buffer
}
// Deal with the tail
// There will be 1 or more items still in the buffer that must be dealt with
echo "Final buf has " . count($buf) . " items\n";
if ( count($buf) > 1 ) {
    echo "Shuffling " . count($buf) . " items\n";
    $shuffled = shuffle($buf);
    if ( ! $shuffled ) {
        throw new Exception('Failed to shuffle');
    }
}
$output = array_merge($output, $buf);

print_r($output);
echo "\n";

推荐阅读