2

So, I am trying to get a list of every possible combination of a set of words.

With the input text "1, 2" and the values being ("1" => "a", "b", "c") and ("2" => "d", "e"), I would get something like:

a, d
b, d
c, d
a, e
b, e
c, e

With the code I have right now, I only get:

a, d
b, d
c, d

How can I get around this?

Code:

foreach ($words as $word)
{
    for ($i = 0; $i < count($array); $i++) //For every value
    {
        $key = array_keys($array[$i])[0];
        if ($word === $key)
        {
            $syn = explode("|", $array[$i][$key]); //Get all synonyms
            foreach ($syn as $s) //For each synonym within
            {

                $potential[] = implode(" ", str_replace($key, $s, $words));
            }
        }
    }
}

The procedure is for every word in the input text, we want to go through our entire array of values. In there, we have other arrays ("original" => "synonyms"). From there, we loop through every synonym and add it to a list of potential combinations.

0

2 Answers 2

2

There are a few steps involved:

  1. narrow down the list of synonyms to only those found in the string
  2. create a template from which to build the final sentences
  3. get all synonym combinations and apply them to the template

The following will do that:

$dict = [
    '1' => ['a', 'b', 'c'],
    '2' => ['d', 'e'],
];

$str = '2, 1';

class SentenceTemplate implements IteratorAggregate
{
    private $template;
    private $thesaurus;

    public function __construct($str, $dict)
    {
        $this->thesaurus = [];

        $this->template = preg_replace_callback('/\w+/', function($matches) use ($dict) {
            $word = $matches[0];
            if (isset($dict[$word])) {
                $this->thesaurus[] = $dict[$word];
                return '%s';
            } else {
                return $word;
            }
        }, $str);
    }

    public function getIterator()
    {
        return new ArrayIterator(array_map(function($args) {
            return vsprintf($this->template, $args);
        }, $this->combinations($this->thesaurus)));
    }

    private function combinations($arrays, $i = 0) {
        if (!isset($arrays[$i])) {
            return array();
        }
        if ($i == count($arrays) - 1) {
            return $arrays[$i];
        }

        // get combinations from subsequent arrays
        $tmp = $this->combinations($arrays, $i + 1);

        $result = array();

        // concat each array from tmp with each element from $arrays[$i]
        foreach ($arrays[$i] as $v) {
            foreach ($tmp as $t) {
                $result[] = is_array($t) ? array_merge(array($v), $t) : array($v, $t);
            }
        }

        return $result;
    }
}

$sentences = new SentenceTemplate($str, $dict);
foreach ($sentences as $sentence) {
    echo "$sentence\n";
}

Demo

Sign up to request clarification or add additional context in comments.

3 Comments

This doesn't seem to work for me. Data: dict ( "hello" => array("hey", "whats up"...), "name" => array("nomenclature"...)) and str = "hello my name is" - The only result I get is 0=Array my is
@AdamM I'll test it again with your input and see what I've missed :)
@AdamM I ran your input with my code and it works okay; I've made a small update because I wasn't using $str at the bottom.
2

Assuming that 1 and 2 are both array you can do nested for loops to get every possible combination.

$one = array("a", "b", "c");
$two = array("d", "e");


$final_array = array();

for($a = 0; $a<sizeof($one); $a++) 
{
    for($b = 0; $b<sizeof($two); $b++) 
    {

            $final_array[] = $one["$a"] . $two["$b"];
    }
}

print_r($final_array);

This will print out

Array ( [0] => ad 
        [1] => ae 
        [2] => bd 
        [3] => be 
        [4] => cd 
        [5] => ce )

Hope this was what you were looking for.

2 Comments

This doesn't help me as I have no idea how many arrays I am going to have. I may have one, I may have one hundred. Hence why I need some sort of function that can handle any amount :)
foreach loops would probably be better than for loops calling sizeof repeatedly.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.