MrYeti09
MrYeti09

Reputation: 17

How to split a word in all possible combinations based on array

I'm working on a fake language generator that anyone can input the values like this for example

d = f
e = k
o = u
n = j
m = p
de = ed
mo = om

So the way it should work, for example the word

demon

can output:

  • fkomj ( D | E | M | O | N )
  • edomj ( DE | MO | N )
  • edpuj ( DE | M | O | N )
  • fkpuj ( D | E | MO | N )

based on the array i supplied, so basically for i need the word split in each combination possible based on my input array

I've tried working with an loop in the word and splitting it in offsets and sizes but didnt gave the result i wanted because it was giving parts that i didnt had in the array

Upvotes: 0

Views: 263

Answers (1)

Nina Scholz
Nina Scholz

Reputation: 386560

You could generate an object with all indices of the found pattern and then collect the parts and map new strings.

function getParts(string, parts) {

    function collectParts(index, parts) {
        if (index === string.length) {
            result.push(parts);
            return;
        }
        if (!indices[index]) return;
        indices[index].forEach(s => collectParts(index + s.length, [...parts, s]));
    }

    var indices = {},
        result = [];

    Object.keys(parts).forEach(function (k) {
        var p = string.indexOf(k);
        while (p !== -1) {
            (indices[p] = indices[p] || []).push(k);
            p = string.indexOf(k, p + 1);
        }
    });

    collectParts(0, []);

    return result.map(a => a.map(k => parts[k]).join(''));
}

console.log(getParts('demon', { d: 'f', e: 'k', o: 'u', n: 'j', m: 'p', de: 'ed', mo: 'om' }));
.as-console-wrapper { max-height: 100% !important; top: 0; }

A shorter approach by using substrings of the given string and using a short circuit to exit longer parts.

function getParts(string, pattern) {

    function collectParts(left, right) {
        if (!left) return result.push(right);
        sizes.some(s => {
            if (left.length < s) return true;
            var key = left.slice(0, s);
            if (key in pattern) collectParts(left.slice(s), right + pattern[key]);
        });
    }

    var sizes = [...new Set(Object.keys(pattern).map(k => k.length))].sort((a, b) => a - b),
        result = [];

    collectParts(string, '');
    return result;
}

console.log(getParts('demon', { d: 'f', e: 'k', o: 'u', n: 'j', m: 'p', de: 'ed', mo: 'om' }));
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 2

Related Questions