Массив (матрица) всех возможных вариантов значений другого массива

virus_net

Новичок
Доброго дня, уважаемые кодеры, любители и профессионалы.

Есть задачка об которую я уже всю голову сломал. Вроде звучит не сложно, но мне не дается хоть ты тресни...
Может кто пнёт в нужную сторону ?

Дано, массив совпадений:
Код:
Array
(
    [1] => мама
    [3] => раму
    [7] => раму
    [8] => мыла
    [13] => мама
)
Где ключ это номер позиции в строке, а значение это некое слово из строки.
Значение в массиве может повторяться, т.к.слова в строке не уникальны, но могут и не повторяться. Размер массива тоже может быть разным.

Что надо:
Создать другой массив, где будут содержаться ключи из первого массива (позиции), всех возможных вариантов ключей из исходного массива с учетом повторений, т.е. все уникальные со всеми уникальными.
  • мама раму мыла ==ключи==> 1, 3, 8
  • мама раму мыла ==ключи==> 1, 7, 8
  • раму мыла мама ==ключи==> 3, 8, 13
  • раму мыла мама ==ключи==> 7, 8, 13
  • мыла мама раму ==ключи==> 8, 13, 3
  • мыла мама раму ==ключи==> 8, 13, 7
  • раму мама мыла ==ключи==> 3, 1, 8
  • раму мама мыла ==ключи==> 7, 13, 8
ну и так далее.

На выходе должно получиться, что-то типа:
Код:
Array
(
    [0] => Array
        (
            [0] => 1
            [1] => 3
            [2] => 8
        )

    [1] => Array
        (
            [0] => 3
            [1] => 8
            [2] => 13
        )
    [2] => Array
        (
            [0] => 7
            [1] => 8
            [2] => 13
        )
    [3] => Array
.....
ну и т.д. все возможные варианты.
Очень надеюсь что понятно изложил.

И вот тут моя "коса нашла на камень". Который день в ступоре...
 
Последнее редактирование:

virus_net

Новичок
Спасибо за ответ, но это не совсем то что нужно по моей задаче.

Там все слова уники, а у меня это не так. И у меня не должно получаться комбинаций вида: мама мама мыла, раму мама раму

UPD:
Составить комбинации из уников я и сам уже составил:
Код:
Array
(
    [0] => Array
        (
            [0] => мама
            [1] => раму
            [2] => мыла
        )

    [1] => Array
        (
            [0] => мама
            [1] => мыла
            [2] => раму
        )

    [2] => Array
        (
            [0] => раму
            [1] => мама
            [2] => мыла
        )

    [3] => Array
        (
            [0] => раму
            [1] => мыла
            [2] => мама
        )

    [4] => Array
        (
            [0] => мыла
            [1] => мама
            [2] => раму
        )

    [5] => Array
        (
            [0] => мыла
            [1] => раму
            [2] => мама
        )
)
А теперь это надо как-то скрестить с повторениями:
Код:
Array
(
    [мама] => Array
        (
            [0] => 1
            [1] => 13
        )

    [раму] => Array
        (
            [0] => 3
            [1] => 7
        )

    [мыла] => Array
        (
            [0] => 8
        )

)

И вот только после этого уже получить финальный массив из комбинаций с повторениями, где уже будут не слова, а ключи.
Но никак не рожу код. Прямо напасть какая то... может в отпуск пора...
 
Последнее редактирование:

fixxxer

К.О.
Партнер клуба
Для начала надо четко поставить задачу.
Откуда взялись группы по 3? Что значит "скрестить с повторениями"?
Я ничего не понял, если честно.

Напиши юнит-тест на пока не работающую функцию, с разными вариантами того, что на входе и что должно получиться на выходе.
Вот как-то так: https://phpunit.readthedocs.io/en/8.3/writing-tests-for-phpunit.html#data-providers
 

virus_net

Новичок
Задача озвучена в первом сообщении. Старался описать максимально доходчиво.

Группы по 3, потому что в приведенном примере, в массиве совпадений (исходный массив, который приведен в первом сообщении), всего 3 уникальных слова.

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

Может на более простом примере понятнее что требуется:
Исходный массив:
Код:
Array
(
    [k1] => a
    [k2] => b
    [k3] => a
)
Массив уникальных значений (в исходном массиве это буквы "а" и "b" ) и их ключей (буква "a" ключ "k1" и ключ "k3", буква "b" ключ "k2"):
Код:
Array
(
    [a] => Array
        (
            [0] => k1
            [1] => k3
        )
    [b] => Array
        (
            [0] => k2
        )
)
Ожидаемый результат:
Код:
Array
(
    [0] => Array
        (
            [0] => k1
            [1] => k2
        )

    [1] => Array
        (
            [0] => k2
            [1] => k3
        )
Т.к. иных комбинаций все уникальные со всеми уникальными с их ключами кроме как:
  • [k1] => a плюс [k2] => b
  • [k2] => b плюс [k3] => a
(в массиве уникальных значений) больше нет

Про юнит-тест не вкурил, т.к. не встречался с этим ранее. Нужно читать и разбираться.
 
Последнее редактирование:

virus_net

Новичок
Неужто на целом ресурсе нет человека который мог бы дать дельный совет ?

Код:
Array
(
    [k1] => Array
        (
            [0] => p1
            [1] => p11
        )

    [k2] => Array
        (
            [0] => p3
            [1] => p7
            [2] => p12
        )

    [k3] => Array
        (
            [0] => p8
        )

)
Код:
Array
(
    [0] => Array
    (
           [0] => p1
           [1] => p3
           [2] => p8
     )
    [1] => Array
    (
           [0] => p1
           [1] => p7
           [2] => p8
    )
    [2] => Array
    (
           [0] => p1
           [1] => p12
           [2] => p8
    )
    [3] => Array
    (
           [0] => p11
           [1] => p3
           [2] => p8
    )
    [4] => Array
    (
           [0] => p11
           [1] => p7
           [2] => p8
    )
    [5] => Array
    (
           [0] => p11
           [1] => p12
           [2] => p8
     )
)

Хоть пните в сторону кого с кем ичить.
 
Последнее редактирование:

WMix

герр M:)ller
Партнер клуба
ты не можешь варазить словами задачу.

выкини все что ты знаешь о массивах и программировании в целом. скажи конечную задачу так, чтоб ее понял любой, без промежуточных решений которые возникли в твоей голове
 

virus_net

Новичок
В сообщении выше я привел то, что на входе и то, что надо получить на выходе. Куда уж ещё выразительнее ?

Вообщем ясно. Хелпа тут можно не ждать.
Всем спасибо.
 

virus_net

Новичок
Ответ найден, наконец, на stackoverflow.

Код:
$a = array (
        array ("a", "b", "c"),
        array ("d", "f"),
        array ("g", "k")
    );

    function fill (&$arr, $idx = 0) {
        static $line = array();
        static $keys;
        static $max;
        static $results;
        if ($idx == 0) {
            $keys = array_keys($arr);
            $max = count($arr);
            $results = array();
        }
        if ($idx < $max) {
            $values = $arr[$keys[$idx]];
            foreach ($values as $value) {
                array_push($line, $value);
                fill($arr, $idx+1);
                array_pop($line);
            }
        } else {
            $results[] = $line;
        }
        if ($idx == 0) return $results;
    }

    print_r(fill($a));
 

fixxxer

К.О.
Партнер клуба
А, дошло.

Чет больно сложный ответ, да еще и нереентерабельный. Все проще.

Формируешь массив вида слово => ключи:
PHP:
    $flipped = [];
    foreach ($in as $key => $value) {
        $flipped[$value][] = $key;
    }
    $flipped = array_values($flipped);
а дальше используешь функцию, которую дал @WMix.
 

virus_net

Новичок
Что и было мной сделано изначально (массив повторений).

Если на последнем приведенном примере массива ("как из"):
PHP:
$flipped = array(
    'k1' => array(
        0 => 'p1',
        1 => 'p11',
    ),
    'k2' => array(
        0 => 'p3',
        1 => 'p7',
        2 => 'p12',
    ),
    'k3' => array(
        0 => 'p8',
    )
);
Применяем Permutations:
PHP:
$permutations = new \drupol\phpermutations\Generators\Permutations($flipped,3);

print_r($permutations->toArray());
Код:
Array
(
    [0] => Array
        (
            [0] => Array
                (
                    [0] => p1
                    [1] => p11
                )

            [1] => Array
                (
                    [0] => p3
                    [1] => p7
                    [2] => p12
                )

            [2] => Array
                (
                    [0] => p8
                )

        )

    [1] => Array
        (
            [0] => Array
                (
                    [0] => p1
                    [1] => p11
                )

            [1] => Array
                (
                    [0] => p8
                )

            [2] => Array
                (
                    [0] => p3
                    [1] => p7
                    [2] => p12
                )

        )

    [2] => Array
        (
            [0] => Array
                (
                    [0] => p3
                    [1] => p7
                    [2] => p12
                )

            [1] => Array
                (
                    [0] => p1
                    [1] => p11
                )

            [2] => Array
                (
                    [0] => p8
                )

        )

    [3] => Array
        (
            [0] => Array
                (
                    [0] => p3
                    [1] => p7
                    [2] => p12
                )

            [1] => Array
                (
                    [0] => p8
                )

            [2] => Array
                (
                    [0] => p1
                    [1] => p11
                )

        )

    [4] => Array
        (
            [0] => Array
                (
                    [0] => p8
                )

            [1] => Array
                (
                    [0] => p1
                    [1] => p11
                )

            [2] => Array
                (
                    [0] => p3
                    [1] => p7
                    [2] => p12
                )

        )

    [5] => Array
        (
            [0] => Array
                (
                    [0] => p8
                )

            [1] => Array
                (
                    [0] => p3
                    [1] => p7
                    [2] => p12
                )

            [2] => Array
                (
                    [0] => p1
                    [1] => p11
                )

        )

)
И как я и говорил - это не то что требовалось.

Тот же массив, но с функцией со stackoverflow:
PHP:
print_r(fill($flipped));
Код:
Array
(
    [0] => Array
        (
            [0] => p1
            [1] => p3
            [2] => p8
        )

    [1] => Array
        (
            [0] => p1
            [1] => p7
            [2] => p8
        )

    [2] => Array
        (
            [0] => p1
            [1] => p12
            [2] => p8
        )

    [3] => Array
        (
            [0] => p11
            [1] => p3
            [2] => p8
        )

    [4] => Array
        (
            [0] => p11
            [1] => p7
            [2] => p8
        )

    [5] => Array
        (
            [0] => p11
            [1] => p12
            [2] => p8
        )
)
Результат который и требовалось получить.

ИМХО: И проще вставить в код одну ф-цию, а не кучу классов.
 
Последнее редактирование:

Фанат

oncle terrible
Команда форума
Очередной блин сео спамер с расчесанным эго.
Пинка ему под зад, а не код на блюдечке.
 
  • Like
Реакции: WMix
Сверху