Как сгруппировать файлы в группы определенного размера в PHP - PullRequest
0 голосов
/ 17 января 2020

Представьте, что у вас есть 10 файлов, которые мне нужно отправить, например:

$ files типа string []

  • 1.jpg - 3.2 МБ
  • 2.jpg - 2,8 МБ
  • 3.jpg - 3,5 МБ
  • 4.jpg - 2,1 МБ
  • 5.jpg - 0,9 МБ
  • 6.jpg - 2,9 МБ
  • 7.jpg - 2,4 МБ
  • 8.jpg - 2,1 МБ
  • 9.jpg - 1,1 МБ
  • 10.jpg - 1,9 МБ

Также у меня есть, например, ограничение в 10 МБ на одно электронное письмо. $ limit

  1. Мне нужно создать группы файлов (массивы или имена файлов), где в каждой группе есть имена файлов, сумма которых меньше, чем $ limit Пример:

    • ['1.jpg', '2.jpg', '3.jpg', '4.jpg'] - НЕПРАВИЛЬНО (11.6MB> $ limit )
    • ['1.jpg', '2.jpg', '3.jpg'] - ОК (9,5 МБ <$ limit) </strong>
  2. Еще лучше, чтобы было как можно меньше групп (например, у вас может быть 10 групп с одним файлом, что бы выполнить эту задачу, но было бы лучше иметь всего несколько групп с большим количеством файлов). как можно ближе к $ limit насколько возможно)

Мне нужно сделать это с чистым PHP или с помощью Laravel при необходимости

Спасибо

ОБНОВЛЕНИЕ: Я знаю, как получить размер файла , мне нужно сгруппировать эти файлы

Ответы [ 2 ]

1 голос
/ 17 января 2020

Мы можем прочитать , чтобы найти как можно меньшего числа групп - комбинаторная NP-сложная задача , но с алгоритмом, таким как Сначала Fit При уменьшении мы получаем результаты, которые должны быть достаточно хорошими. Вот пример реализации:

$files = array('1.jpg', '2.jpg', '3.jpg', '4.jpg', '5.jpg', '6.jpg', '7.jpg', '8.jpg', '9.jpg', '10.jpg');
$sizes = array(3.2, 2.8, 3.5, 2.1, 0.9, 2.9, 2.4, 2.1, 1.1, 1.9);
$limit = 10;
$files = array_combine($files, $sizes);
# algorithm "First Fit Decreasing"
arsort($files); # sort the files by descending size
$groups = array();
foreach ($files as $file => $size)
{   # insert the files one by one
    # so that each is placed in the first group that still has enough space
    foreach ($groups as &$group)
        if (array_sum($group)+$size <= $limit)
        { $group[$file] = $size; continue 2; }
    # if there is not enough space in any of the groups that are already open,
    # open a new one
    $groups[][$file] = $size; 
}
unset($group);
# the filenames are the keys within each group
foreach ($groups as $group) print_r(array_keys($group));
0 голосов
/ 17 января 2020

Здесь вы можете найти методы для ввода типа файла: https://laravel.com/api/5.8/Illuminate/Http/Testing/File.html

Чтобы узнать размер файла, вы можете использовать этот метод:

$img_size = $request->file('file')->getSize();

У вас уже есть самое важное, теперь это будет зависеть от вас, как запрограммировать решение;)

Я надеюсь, что помог

PD: извините за мой Engli sh

...