@Pseudoquater

Как из текстового файла вывести 15 случайных строк?

Файл 1.txt - текстовой файл , представляющий из себя 1тыс строк текста на русском языке. Задача кода - вывести 15 случайных строк из текстового файла без перемешивания. Нижеприведенный код выполняет эту функцию, но он каждый раз перемешивает файл, что при множественном обращении к серверу, затрудняет работу скрипта. Как вывести 15 случайных строк без перемешивания? Т.е. при множественном обращении сервера к скрипту, каждые 15 новых строк должны отличаться. Ну и разумеется строки доллжны быть написаны также как и в самом файле - построчно (т.е. строки не соединяем никак)
<?php
$arr = file('https://site/1.txt');
shuffle($arr);
$res = array_slice($arr, 0, 15);
foreach ($res as $str) {
  $get  = mb_detect_encoding($str, array('utf-8', 'cp1251'));
  echo iconv($get, 'UTF-8', $str);
}
?>

Очень бы хотелось использовать вывод кириллицы как в коде выше, потому что был геммор на одном из вариантов сервера, где строки выводились аброказяброй. Код выше решил эту проблему.
Ранее вывод коряво осуществлялся таким методом:
foreach($res as $str){
  echo htmlspecialchars($str);
}
?>


Формат вывода:
русский текст случайная строка из файла 1.txt
русский текст случайная строка из файла 1.txt
русский текст случайная строка из файла 1.txt
русский текст случайная строка из файла 1.txt
...
русский текст случайная строка из файла 1.txt
  • Вопрос задан
  • 166 просмотров
Пригласить эксперта
Ответы на вопрос 2
v3shin
@v3shin
Веб-шаман
$arrLength = count($arr);
$lines = [];
while (count($lines) < 15) {
	$n = mt_rand(0, $arrLength-1);
	$lines[$n] = $n;
}
ksort($lines);
var_export($lines); // номера нужных строк

Ну, и запилите проверку на количество строк в файле, чтобы не улететь в бесконечный цикл.
Ответ написан
@Vitsliputsli
Накидал вариант для поиска случайных строк в очень больших файлах. Это не совсем оптимально для конкртеного случая автора, но может быть будет кому-то интересно в других случаях.
$fileName = '1.csv';
$lineLength = 1024;
$linesCount = 15;

$handle = fopen($fileName, "r");
$fileSize = filesize($fileName);
$data = [];
if ($fileSize !== 0) {
   for ($num = 1; $num <= $linesCount; $num++) {
       $rand = rand(0, $fileSize);
       fseek($handle, $rand);
       $firstPointer = null;
       do {
           fgets($handle); // trash
           $pointer = ftell($handle);
           if ($pointer === $fileSize) {
               fseek($handle, 0);
               $pointer = 0;
           }
           if ($pointer === $firstPointer) { // loop detect
               continue 2;
           }
           $firstPointer = $firstPointer ?? $pointer;
       } while (array_key_exists($pointer, $data));
       $data[$pointer] = fgets($handle);
   }
}
ksort($data); // sort by order in file
var_dump($data);

Я здесь не делал защиты от ошибок файловых функций, в этом случае результат может быть неожиданным. Для защиты нужно обернуть все файловые функции и при ошибке выкидывать Exception, а не эти тупые php-шные false. Ну и помнить про ограничение длины строки в $lineLength.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Похожие вопросы