Search code examples
javascriptarraysfor-loopartificial-intelligence

How do I filter a string through multiple arrays and choose the one with the most resemblance


I'm not asking for a code-example, just asking for the best way possible

So I'm currently creating a robot-answered helpdesk which answers with specific answers (like the contact-address) when it recognizes specific words (like if a user enters 'stuur mail' it will say 'Als je een mailtje wil sturen kan dit naar help@wordquest.nl')

It works with arrays, so there's an array

mailText['stuur', 'mail', 'verzend'];

And there's a function (checkMail()) that checks how much of the given text (from a input field) is in the array. So if a user enters 'hoe stuur ik een mail' it recognizes 'stuur' and 'mail' and knows that 66% percent of the words from the mailText array are used. I currently have two arrays like this. And it works, with 4 if-statements to check which one fits the users input best, but I really don't want to write hundreds of if-statements comparing arrays and creating a function for every array.

The current JS is

window.onkeydown = function (event) {
    if (event.keyCode == 13) {
        checkQuestions(document.getElementsByClassName('inputField')[0].value);

        document.getElementsByClassName('inputField')[0].value = '';

        if (event.preventDefault) event.preventDefault(); // This should fix it
            return false; // Just a workaround for old browsers
    }
}

var mail = ['stuur', 'mail', 'verzend'];
var verzenden = ['kost', 'verzend', 'pakket'];

var errorText = '<h1>An error has occured...</h1><br>There are no answers with the current search query...';

var mailText = 'Als je een mailtje wil sturen kan dit naar <a 
href="mailto:help@wordquest.nl">help@wordquest.nl</a>';
var sendText = 'Verzendkosten verschillen per pakket';

var answers = [];

function checkQuestions(quest) {
    console.log('');
    answer = 0;
    finalText = errorText;
    answers = [];

    mailNum = checkMail(quest);
    sendNum = checkSend(quest);

    if (mailNum > sendNum) {
        answers.push(mailText);
    } else if (sendNum > mailNum) {
        answers.push(sendText);
    } else if (sendNum == mailNum && sendNum != 0) {
        answers.push(mailText);
        answers.push(sendText);
    } else {
        answers.push(errorText);
    }

    setAnswer();
}

function checkMail(question) {
    chance = 0;
    indent = 100 / mail.length;
    for (i = 0; i < mail.length; i++) {
        if (question.includes(mail[i])) {
            chance = chance + indent;
        }
    }
    console.log('mail is ' + chance + '%');
    return chance;
}

function checkSend(question) {
    chance = 0;
    indent = 100 / verzenden.length;
    for (i = 0; i < verzenden.length; i++) {
        if (question.includes(verzenden[i])) {
            chance = chance + indent;
        }
    }
    console.log('verzenden is ' + chance + '%');
    return chance;
}

var finalAns = [];

function setAnswer() {
    finalAns = [];

    if (answers[0] != errorText) {
        finalAns.push('<b>Er zijn ' + answers.length + ' antwoorden gevonden!</b>');
    }

    for (i = 0; i < answers.length; i++) {
        finalAns.push('<p>' + answers[i] + '</p>');
    }

    document.getElementsByClassName('answers')[0].innerHTML = finalAns.join('');
}

Current page (with HTML): https://codepen.io/timyboy12345/pen/YEpmZz

I know this is probably not the best way to do this, but it's just a hobby-project...

So does anyone have a good idea on how to make a function that compares the users input to all array's with answer-combinations (+50 in the end probably) without creating a function for every array, and give the user a correct text (I'm using predefined variables at the moment) with the answer to their question.


Solution

  • You could use nested arrays and use a counter to track the number of words matched. Then you calculate the percentage of accuracy and use a final array to know which array was correctly answered.

    Pseudo-code for the loops:

    for i = 0; i < arraysToMatch; i++
        nbMatched = 0
        foreach answer in answerArray[i]
            if answer is in arraysToMatch[i] then
                ++nbMatched
            end if
        end foreach
    
        // Here calculate the accuracy and if good use i       
    
    end for
    

    That way you don't need a function for each arrays. However, you will need to pair the matching array with the answer array.