Рандомные строки (php)

A
На сайте с 12.09.2011
Offline
149
469
Здравствуйте помогите чуть доработать простенький код:

<?php 

$arr = file("C:/content/file.txt"); 

$keys = array_rand($arr, 6);

foreach ($keys as $key) {

printf($arr[$key]);

}

?>

Данный код берёт рандомно 6 строчек из file.txt 
Но когда в file.txt  меньше 6 строк он выдаёт ошибку.... Нужно чтобы он работал с меньшем количеством строк, но при этом брал максимум 6 (и брал всегда максимум когда он есть, когда их нету, брал столько сколько есть).  Спасибо



Ищу работу помощником Вебмастера, долгое время занимался сайтами. https://t.me/fania008
M3
На сайте с 09.02.2022
Offline
106
#1
<?php 

$arr = file("C:/content/file.txt");

// Получаем количество строк в массиве
$count = count($arr);

// Определяем, сколько строк нужно выбрать (максимум 6)
$numToSelect = min($count, 6);

// Получаем случайные ключи
$keys = array_rand($arr, $numToSelect);

foreach ($keys as $key) {
    printf($arr[$key]);
}

?>
ArbNet
На сайте с 27.10.2019
Offline
146
#2
$num=6;// количество рандомных ключей массива
$cnt=count($arr);// размер массива
if($num>$cnt)$num=$cnt;
$keys = array_rand($arr,$num);
A
На сайте с 12.09.2011
Offline
149
#3
Супер!  Спасибо  работает:)
LEOnidUKG
На сайте с 25.11.2006
Offline
1774
#4

<?php

$mass=file('file.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);

shuffle($mass);

$mass=array_slice($mass, 0, 6);

print_r($mass);


✅ Мой Телеграм канал по SEO, оптимизации сайтов и серверов: https://t.me/leonidukgLIVE ✅ Качественное и рабочее размещение SEO статей СНГ и Бурж: https://getmanylinks.ru/ ✅ Настройка и оптимизация серверов https://getmanyspeed.ru/
Жорик
На сайте с 11.09.2006
Offline
215
#5

Опередил меня, ну тогда получифашистгранату 🤣


<?php

$arr = [1, 2, 3, 4];

print_r(array_slice([shuffle($arr), $arr][1], -6));
Александр Воробьев
На сайте с 03.02.2020
Offline
55
#6

А если файл на несколько гигов - зачем его весь читать и смешивать?

Вариант:

echo 'result ', getRandom('e.php', 6), PHP_EOL;

function getRandom(string $fileName, int $maxIndex = 6, bool $notEmpty = true): string
{
    $result = '';
    $index = random_int(0, $maxIndex - 1);
    $handle = fopen($fileName, "r");
    if ($handle) {
        $i = 0;
        $accum = [];
        while ($i <= $index && ($line = fgets($handle)) !== false) {
            if ($notEmpty && trim($line) === '') {
                continue;
            }
            $accum[] = $line;
            if ($i === $index) {
                $result = $line;
                break;
            }
            ++$i;
        }
        fclose($handle);
        if ($result === '' && count($accum) > 0) {
            $index = array_rand($accum);
            $result = $result[$index];
        }
    }
    return trim($result);
}
Александр Воробьев
На сайте с 03.02.2020
Offline
55
#7

Опечатка у меня

if ($result === '' && count($accum) > 0) {
            $index = array_rand($accum);
            $result = $accum[$index];
        }

конечно же из accum

S3
На сайте с 29.03.2012
Offline
367
#8

Вот поэтому я люблю пайтон - все проще и лаконичнее)))

import os
import random

def random_row(f_name):

    with open(f"{os.path.dirname(os.path.realpath(__file__))}/{f_name}", "r") as f:
        rows = f.read().splitlines()  # Read all lines into a list, removing newline characters
        counter = 6 if len(rows) > 6 else len(rows)
        
        if rows:  # Ensure rows is not empty
            for line, item in enumerate(range(0, counter)):
                random_row = random.choice(rows)  # Pick a random line from rows
                print(f"{line}: Random row: {random_row}")
Александр Воробьев
На сайте с 03.02.2020
Offline
55
#9
Sly32 #:
Вот поэтому я люблю пайтон - все проще и лаконичнее)))

Хм. если я правильно понял это аналог не моего скрипта. Здесь так же читается весь файл. Причем явно надо именно указать что надо разнести в массив построчно.  А файл ведь может и несколько гигабайт и терабайт.

Может тут, по крайней мере, не просто splitlines  а регуляркой взять, чтоб не пыталось массив на 100500 элементов создавать

Т.е., на мой взгляд, даже скрипт великого разработчика фреймворков выглядит лаконичнее (хотя там есть еще возможность написать лаконичнее - правда, по сути, за счет сахара)

S3
На сайте с 29.03.2012
Offline
367
#10
Александр Воробьев #:
Хм. если я правильно понял это аналог не моего скрипта.

вот аналог

def get_random_line(file_name: str, max_index: int = 6) -> str:
    result = ''
    index = random.randint(0, max_index - 1)
    with open(f"{os.path.dirname(os.path.realpath(__file__))}/{f_name}", "r") as f:
        i = 0  
        accum = []  
        for line in f:
            if line.strip() == '':
                continue
            accum.append(line)
            if i == index:
                result = line
                break
            i += 1
        if result == '' and accum:
            result = random.choice(accum)  
    return result.strip()

все равно короче)

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий