all files / src/ multiplicator.js

97.96% Statements 48/49
80% Branches 8/10
100% Functions 4/4
97.87% Lines 46/47
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90                16×                               16× 16× 32× 32×   16×   16×                                      
/*
 * @author David Menger
 */
'use strict';
 
const assert = require('assert');
 
function expand (combinations, vector) {
    if (combinations.length === 0) {
        return vector.map(w => [w]);
    }
    return combinations
        .reduce((ret, combination) => {
            vector.forEach((word) => {
                ret.push([...combination, word]);
            });
            return ret;
        }, []);
}
 
function tokenizeText (intent) {
    let start = 0;
    let end;
    const tokens = [];
 
    for (let i = 0; i <= intent.entities.length; i++) {
        if (i < intent.entities.length) {
            end = intent.entities[i].start;
        } else {
            end = undefined;
        }
 
        tokens.push(intent.text.slice(start, end));
 
        if (i < intent.entities.length) {
            start = intent.entities[i].end;
        }
    }
 
    return tokens;
}
 
function generateOptions (intent, combinations) {
    const tokens = tokenizeText(intent);
    const expectedWordsLength = tokens.length - 1;
    const join = new Array(tokens.length + expectedWordsLength);
    let i;
    let pos;
    for (i = 0; i < tokens.length; i++) {
        pos = i * 2;
        join[pos] = tokens[i];
    }
    return combinations.map((words) => {
        assert(words.length === expectedWordsLength);
        for (i = 0; i < words.length; i++) {
            pos = i * 2;
            join[pos + 1] = words[i];
        }
        const text = join.join('');
 
        return Object.assign({}, intent, {
            text,
            entities: [] // not necessary now
        });
    });
}
 
function multiplicator (intent, getVariants) {
    Iif (!Array.isArray(intent.entities)) {
        return Promise.resolve([intent]);
    }
 
    intent.entities.sort((a, b) => (a.start < b.start ? -1 : 1));
 
    const variantsPromise = intent.entities
        .map(entity => getVariants(entity.entity, entity.value));
 
    return Promise.all(variantsPromise)
        .then((variants) => {
            const combinations = variants
                .reduce((c, entityVariants) => expand(c, entityVariants), []);
 
            return generateOptions(intent, combinations);
        });
}
 
module.exports = {
    multiplicator
};