Приветствую, уже 2 дня туплю над реализацией казалось бы простой функции... на вход поступает массив массивов произвольной длины, типа { a=>[1,2,3,4], b=>[00,aa], c=>[F] } На выходе нужно получить такое (порядок не важен): { 1 00 F, 1 aa F, 2 00 F, 2 aa F, 3 00 F, ... и так далее } т.е. нужно получить все возможнные комбинации элементов всех переданных массивов. Никак не пойму как правильно завернуть это в циклы... Смог родить такое: PHP: function Multiply ($inputarray){ $result=array(); $prevRes=array(); foreach ($inputarray as $column=>$list){ if(!empty($prevRes)){ foreach ($list as $row) { //перебираем список foreach ($prevRes as $line){//перебираем уже записанный результат $newline=(string) $line.' | '.$row; //var_dump($newline); //перемножаем с тем что есть $result[]=$newline; } $prevRes=$result; $result=array(); } } else //первый столбец $prevRes=$list; } return $prevRes; } Но это неправильно. выводит : [0]=> string(15) "1 | 00 | aa | F" [1]=> string(15) "2 | 00 | aa | F" [2]=> string(15) "3 | 00 | aa | F" [3]=> string(15) "4 | 00 | aa | F" т.е. несколько элементов 1 массива попадают в 1 результирующую строку.. что ожидаемо, раз у меня идет перебор всех элементов каждого массива... Но блин, не могу понять как иначе сделать... пробовал переписать через for - но прихожу к тому же самому..
Сначала объедините значения двух массивов в новый массив. Новый массив "объедините" с третьим в другой новый массив.
Так я же так и делал ведь! Значит все правильно было. Да, просто ошибся во вложенности форычей - а так все верно. Ок, спасибо. Получился такой код правильный: PHP: function Multiply($inputarray){ //input array of column arrays $result=array(); $prevRes=array(); // 1 column foreach ($inputarray as $column=> $list) { if(empty($result)){ $result=$list; } else{ foreach ($result as $line) { foreach ($list as $row) { $newline=(string) $line.'|'.(string)$row; $prevRes[]=$newline; } } $result=$prevRes; $prevRes=array(); } } return $result; }
На тысяче элементов такой алгоритм займёт слишком много времени. Предлагаю расписать на бумаге все варианты в три строки и найти закономерность. Для наглядности лучше чтобы не было членов со всего одним вариантом.
Прилично, да. Если эти самые элементы не изменяются, то полученный массив лучше записать в файл. А если элементы, время от времени меняются, то только перебор.
Я и не предлагаю сохранять. Например, если всего два массива, и в каждом два элемента: Код (Text): a, a, b, b x, z, x, z a и b повторяются по два раза подряд. Если генерировать варианты как параллельные массивы, можно использовать array_fill() для быстрого заполнения повторяющися элементов. Если три массива, то x, x, z, z будет повторяться дважды, можно использовать array_merge() чтобы приклеивать паттерн столько раз, сколько нужно. Если длина элементов известна, то можно все это сделать с помощью параллельных строк, заполняемых паттернами с помощью str_repeat().
Ключевое слово "если". Я об этом. А так-то, да. Еще можно такое решить силами sql, но вряд ли быстрей.
Входной массив задается пользователем - данные извлекаются из гугл таблиц, где каждый столбец это массив значений. По поводу оптимизации, как-то пока не улавливаю.. предлагаете сперва проверять каждый массив на содержание повторяющихся элементов?
Нет, дело не в повторяющихся элементах массива, а в повторах при переборе. Честно говоря, не совсем понял с каким массовом работает ваша финальная функция. И какой у неё вывод?
Вот накидал для двух массивов, генерацию 36 вариантов одним циклом в 3 итерации: https://sandbox.onlinephpfunctions.com/code/69973ebb2ea563c81f546b790b5e0bcddadc16df
Да, очень интересное решение, но пока не соображу как его адаптировать для произвольного числа массивов не придя к перебору, чтобы можно было протестировать.. Пример реальных данных: Число столбцов и длина могут быть произвольные. Можно сказать что функционал соответствует веб-сервисам по типу peresekator. ru, только для неограниченного числа списков