janfichter
@janfichter
веб-мастер

Как сделать рандом без повторений из PhpExcel?

У меня есть php скрипт вывода товаров из файла эксель на сайт, без использования БД, с помощью библиотеки PhpExcel. Все работает отлично, выводятся рандомно 10 товаров из списка. Но товары периодически повторяются, иногда идут два одинаковых подряд. Как реализовать все это без повторений?

Мой код:

<?php
 
require_once 'PHPExcel-1.8/Classes/PHPExcel.php';
$excel = PHPExcel_IOFactory::load('catalog.xlsx');
 
$excel->setActiveSheetIndex(0);

echo "<table border='1'>";

$count = 0;

for ($i=2; $excel->getActiveSheet()->getCell('A'.$i)->getValue() != ""; $i++) $count = $i;


for ($a=0; $a < 10; $a++) { 
    $key = rand(2,$count);

    $description = $excel->getActiveSheet()->getCell('A'.$key)->getValue();
    $image = $excel->getActiveSheet()->getCell('B'.$key)->getValue();
    $price_new = $excel->getActiveSheet()->getCell('C'.$key)->getValue();
    $price_old = $excel->getActiveSheet()->getCell('D'.$key)->getValue();
    $discount = $excel->getActiveSheet()->getCell('F'.$key)->getValue();
    
    echo "
        <tr>
            <td>".$description."</td>
            <td><img src='images/".$image."' width='150' height='150'></td>
            <td>".$price_new."</td>
            <td><s>".$price_old."</s></td>
            <td>".$discount."%</td>
        </tr>
    ";
}

echo "</table>";

?>
  • Вопрос задан
  • 71 просмотр
Решения вопроса 1
ipatiev
@ipatiev Куратор тега PHP
Потомок старинного рода Ипатьевых-Колотитьевых
Пропуск повторений при генерации уникальных значений - это универсальный алгоритм, который не имеет отношения к phpexcel.
Программисту очень важно уметь декомпозировать задачи. Не относиться к программе как пользователь к чёрному ящику, который что-то там внутри себя делает, "на вход данные, на выход результат", а понимать, за что отвечает каждый элемент программы. В данном случае у нас есть получение в цикле случайных значений, и необходимо обеспечить уникальность. А конкретное использование этих значений нас не интересует.

Исходя из здравого смысла, в данном случае (когда из потенциально большого массива значений надо выбрать несколько случайных) чтобы избежать повторений, надо запоминать все уже использованные значения. Для этого подойдёт массив.
А для проверки идеально подойдет цикл do while, это редкий случай его использования. просто генерируем новые ключи до тех пор, пока не найдётся ещё не использованный.
do {
    $key = rand(2,$count);
} while (array_key_exists($key,$exists));
$exists[$key] = true;


Важно не забыть определить пустой массив $exists перед началом цикла.

Так же этот метод отлично подойдёт, если случайные значения не берутся из готового списка, а генерируются на лету.

Если же количество требуемых случайных значений сравнимо с количеством всех данных, то удобнее будет сначала сгенерировать массив всех ключей и перемешать его
$keys = range(2, $count);
shuffle($keys);
for ($a=0; $a < 10; $a++) {
    $key = $keys[$i];
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы