2

I have an input field where I expect users to type text that contains 1 of many keywords that will trigger different audio files depending on the keyword. (I know that's not really smart from UX point of view but that's just a mockup/demo of a virtual assistant).

I'm using this code but I feel I can do much better, can you suggest some alternatives?

    keyword1 = "music";
    keyword2 = "news";
    keyword3 = "weather";
    keyword4 = "cooking";
    keyword5 = "pasta";
    keyword6 = "tech";

    if(text.search(keyword1)!=-1) {
      audio.src = a_music;
      audio.play();
    } else if(text.search(keyword2)!=-1){
      audio.src = a_news;
      audio.play();
    } 
   [...]
  }
Gusepo
  • 837
  • 2
  • 13
  • 26
  • Do a key->value pair array and loop the array. It would be quite nice to actually have a fiddle to give you an example, it's just pure theory here (besides, as long as the problem is solved already it may result in being off topic here). – briosheje Oct 24 '17 at 15:16

5 Answers5

5

You could create an object with the keyword as key and the file url as value and then iterate over the keys to check if the text matches a keyword.

const config = { 
  'music': 'musicUrl',
  'news': 'newsUrl',
  'weather': 'weatherUrl',
  'cooking': 'cookingUrl',
  'pasta': 'pastaUrl',
  'tech': 'techUrl'
};

function match(input, obj) {
  var matched = Object.keys(obj).find(key => input.toLowerCase().search(key) > -1);
  return obj[matched] || null;
}

console.log(match('cats weather dogs', config));
console.log(match('cats tech dogs', config));
console.log(match('cats dogs', config));
cyr_x
  • 13,987
  • 2
  • 32
  • 46
  • 1
    Pretty good one here, I would only add a `toLowerCase` and eventually check whether the matched key exists in the config. – briosheje Oct 24 '17 at 15:26
  • Good point, added it. My match function was intended to return `undefined` if nothing was found. But changed it to return `null` if nothing was found. – cyr_x Oct 24 '17 at 15:28
2

You should use an array of keywords instead of one different variable per word. Then it's a piece of cake :

const keywords = ["music","news","weather","cooking","pasta","tech"]

const text = "let's play some music"

if( keywords.some(keyword => text.includes(keyword) )) {
    console.log("Found")
      // audio.src = a_music;
      // audio.play();
}
Jeremy Thille
  • 26,047
  • 12
  • 43
  • 63
1

Using a regex here seems a nice approach to me

let keywords = {
  music: 'musicSample',
  news: 'newsSample',
  weather: 'weatherSample',
  cooking: 'cookingSample',
  pasta: 'pastaSample',
  tech: 'techSample'
}

function searchKeywords (text) {
  let keys = Object.keys(keywords)
  let re = new RegExp('(' + keys.join('|') + ')', 'g')
  
  return text.toLowerCase().match(re)
}

console.log(searchKeywords('I love music and tech'))

// Play the first encountered word or queue every word to play consecutively what you found
console.log(searchKeywords('Mama is cooking some pasta')[0])
3Dos
  • 3,210
  • 3
  • 24
  • 37
0

Perhaps an array?

var array = ["music", "news", "weather", "cooking", "pasta", "tech"];

for(var i = 0; i < array.length; i++){
    if(text.includes(array[i])){
    //do something with i
    break;
  }
}
Sam
  • 608
  • 4
  • 11
0

Here's an example of searching for keywords in a list of strings that allows for ambiguous order of present keywords.

var keywords = [
    'music',
    // 'news',
    // 'weather',
    // 'cooking',
    // 'pasta',
    'tech',
]

var source = [
    "Create a database and tables",
    "What is up with singing",
    "Why is it cold outside",
    "What time is it",
    "How can I set up an appointment",
    "How to make you're own music",
    "Combining music and technology",
]

function search(keywords, source) {
    var re = new RegExp('(' + keywords.join('|') + ')', 'g')
    var results = []
    for (var i = 0; i < source.length; i++) {
        const text = source[i];
        var result = text.toLowerCase().match(re)
        if (result != null || result != null) {
            results.push(text)
        }
    }
    return results
}

var results = search(keywords, source)

console.log(results)
openwonk
  • 14,023
  • 7
  • 43
  • 39