-3

The following array contains entries for a competition. Some participants are shown more than others, hence the times they participate into this.

For example "pounho" has better chances than "vinylin". This is why he has more occurences than "vinylin" in the array.

My question is how to select 3 results out of the following example array, but the results must be unique, no repetitions?

Because currently, I can show 3 results, but there is repetition, for example deou, deou, pounho.

I don't want to remove duplicates. I want the code to take into consideration that the participant "pounho" has better chances than "vinylin".

Array
(
    [0] => pounho
    [1] => pounho
    [2] => pounho
    [3] => panony
    [4] => mamich
    [5] => Deou
    [6] => Deou
    [7] => vinylin
    [8] => laids
    [9] => laids
)
AbraCadaver
  • 78,200
  • 7
  • 66
  • 87
EnexoOnoma
  • 8,454
  • 18
  • 94
  • 179

5 Answers5

2
$inputArray = [...];

$backuppedArray = $inputArray;

$randomlySelected = [];
while(count($randomlySelected) < 3 && count($backuppedArray) > 0){
    $randomItem = $backuppedArray[array_rand($backuppedArray)];
    if(!in_array($randomItem, $randomlySelected)){
        $randomlySelected []= $randomItem;
        $backuppedArray = array_diff($backuppedArray, array($randomItem));
    }
}

updated answer, the more times participant is in array the more chance he has to be in random pick, it's simplest code to achieve it I could imagine

bestestefan
  • 852
  • 6
  • 20
  • I don't want to remove duplicates. I want the code to take into consideration that the participant "pounho" has better chances than "vinylin". – EnexoOnoma Jun 05 '18 at 20:14
  • @EnexoOnoma it has to be random 3 participants or top3 participants? – bestestefan Jun 05 '18 at 20:15
  • random participants – EnexoOnoma Jun 05 '18 at 20:15
  • @EnexoOnoma how about this – bestestefan Jun 05 '18 at 20:19
  • 1
    When adding `$randomItem` to `$randomlySelected`, you might want to also remove all values that match `$randomItem` from `$inputArray`, as this currently could be dangerously inefficient. – Patrick Q Jun 05 '18 at 20:27
  • 1
    @stetoc It would be `array_diff($backuppedArray, array($randomItem))` (both arguments need to be arrays), but yeah, that's the idea. – Patrick Q Jun 05 '18 at 20:32
  • @stetoc thank you for this. I am trying it out. One question though. How do I echo the names instead of the number? – EnexoOnoma Jun 05 '18 at 20:36
  • @stetoc OP can decide if it's good, but this should at least accomplish the goal on a basic level. I'm not a statistician, so I'm not really sure if this if this is precise from a probability standpoint (on the first pick, something could have a 20% chance, but then a 50% chance on the second pick, is that how it should be? I don't know), but it could be "good enough". – Patrick Q Jun 05 '18 at 20:38
  • 1
    @PatrickQ that's how I understood it - like you're on lottery where there is only one price per participant but you can buy many tickets - if you buy 5 tickets you have 5 times greater chance of being picked than someone who bought 1 ticket but you can still win one prize, if one person is selected I think it doesn't matter if he bought 1 or 100 tickets - he is selected and cannot be selected in second pick, so others have their own odds of being picked – bestestefan Jun 05 '18 at 20:40
  • @EnexoOnoma what do you mean by 'names' and not 'number'? if you have your array looking like in example, if 'number' is e.g. `0` then `name` for this number would be `$array[0]`, I don't know what you want to achieve – bestestefan Jun 05 '18 at 20:40
  • @stetoc I mean that I get something like this `Array ( [0] => 8 [1] => 4 [2] => 0 )` instead of the actual participant names – EnexoOnoma Jun 05 '18 at 20:44
  • @EnexoOnoma yeah I forgot about it, `array_rand` returns id of item instead of value, you need to grab it from original array, check updated answer – bestestefan Jun 05 '18 at 20:46
  • @stetoc the problem with this answer is that if you have only 1 element in the array it crashes the server – EnexoOnoma Jun 13 '18 at 17:02
1

Select a random element of the array, then remove all copies of that element. Do this 3 times to get 3 different elements.

$results = array();
for ($i = 0; $i < 3; $i++) {
    $index = array_rand($array);
    $selected = $array[$index];
    $results[] = $selected;
    $array = array_diff($array, array($selected));
}
Barmar
  • 741,623
  • 53
  • 500
  • 612
0

Not sure about the efficiency, especially with huge arrays, but; retrieve the first 3 values and check if they are unique. If not unique, shuffle and try again. Values with a higher frequency will have a better chance of being in the first 3:

while(count($result = array_unique(array_slice($array, 0, 3))) < 3){ shuffle($array); }
AbraCadaver
  • 78,200
  • 7
  • 66
  • 87
-1

You need array_unique

$array2 = array_unique($array);
print_r($array2);
mayersdesign
  • 5,062
  • 4
  • 35
  • 47
-1

This snippet will "rank" the items in the array:

$count = array_count_values($array); //Counts values and makes new array
arsort($count); //Sort that array high to low
$keys = array_keys($count); //Split the array so we can find the key that occurs the most
echo "The top v is $keys[0][1] with $keys[0][0] occurrences."
mayersdesign
  • 5,062
  • 4
  • 35
  • 47