mister movie
mister movie

Reputation: 103

javascript match only certain letters in array

I'm using the below in a javascript Q & A chatbot. To answer for example "what is AG in the periodic table? Answer is Silver.

if ((input.search("(what is|what's)") != -1) && (input.search("(periodic table)") != -1)) {
    document.result.result.value = "Hmmmm, I don't know. Try Google!";
    for (i = 0; i < Periodic_Tables.length; i++) {
        Periodic_Table = Periodic_Tables[i].split('=');
        if (input.indexOf(Periodic_Table[0]) != -1) {
            document.result.result.value = Periodic_Table[1];
        }
    }
    return true;
}

Then I have in another file the array laid out like this:

Periodic_Tables=new Array(

"h=Hydrogen", 
"he=Helium", 
"li=Lithium",
"be=Beryllium",
"b=Boron", 
"c=Carbon", 
"n=Nitro­gen", 
"o=Oxygen",
"f=Fluorine", 
"ne=Neon", 
"na=Sodium",
"mg=Magnesium", 
"ag=Silver" 
);

My problem is because the table symbols are only 1 or 2 letters it's matching a lot of wrong things. How can I set this up where "only" b matches boron, be matches beryllium. etc I've looked a word boundaries but can seem to figure out how to use them here.

Upvotes: 0

Views: 1806

Answers (5)

anubhava
anubhava

Reputation: 785098

Instead of this code block which is checking if input contains a symbol:

if (input.indexOf(Periodic_Table[0]) != -1) {
   document.result.result.value = Periodic_Table[1];
}

You should check for equality like this:

Periodic_Tables=new Array("h=Hydrogen", 
  "he=Helium", "li=Lithium", "be=Beryllium", "b=Boron", "c=Carbon", "o=Oxygen",
  "f=Fluorine", "ne=Neon", "na=Sodium", "mg=Magnesium", "ag=Silver");

function Parse(input) {
   input=input.toLowerCase(); 
   input=input.replace(/[!|?|,|.]/g,""); 
   if (input.search(/\bu\b/)!=-1) input=input.replace(/\bu\b/,"you");
   if (input.search(/\br\b/)!=-1) input=input.replace(/\br\b/,"are");
   if (input.search(/\bk\b/)!=-1) input=input.replace(/\bk\b/,"ok");
   if (input.search(/\by\b/)!=-1) input=input.replace(/\by\b/,"why");

   var words=input.split(" ");
   var result = "Hmmmm, I don't know. Try Google!";
   if ((input.search("(what is|what's)") != -1) && (input.search("(periodic table)") != -1)) {
       for (var w=0; w<words.length; w++) {
          for (i=0; i<Periodic_Tables.length; i++) {
              Periodic_Table = Periodic_Tables[i].split('=');
              if (words[w] == Periodic_Table[0]) {
                  result = Periodic_Table[1];
                  return result;
              }
          }
       }
   }
   return result;
}
alert(Parse("what is h in periodic table"));

DEMO: http://jsfiddle.net/MnyFP/1/

Upvotes: 1

mister movie
mister movie

Reputation: 103

I can't seem to get anything to work within the Q and A bot. So I put up a demo here: http://www.frontiernet.net/~wcowart/aademo.html

Or here is the code: I tried many of the various answers presented. Maybe I'm not implementing them right.

<HTML> 
<HEAD>
<TITLE>ChatterBot Page</TITLE>

<script language="JavaScript">

Periodic_Tables=new Array(

"h=Hydrogen", 
"he=Helium", 
"li=Lithium",
"be=Beryllium",
"b=Boron", 
"c=Carbon", 
"n=Nitro­gen", 
"o=Oxygen",
"f=Fluorine", 
"ne=Neon", 
"na=Sodium",
"mg=Magnesium", 
"ag=Silver" 
);

var message = new Array(); 

var randomnum; 
var flagrandom;

function Parse() { 
var input = new String(document.chat.input.value); 

document.chat.input.value=""; 
input=input.toLowerCase(); 

word=input.split(" ");
num_of_words=word.length;

input=input.replace(/[!|?|,|.]/g,""); 
word=input.split(" ");



if (input.search(/\bu\b/)!=-1) input=input.replace(/\bu\b/,"you");
if (input.search(/\br\b/)!=-1) input=input.replace(/\br\b/,"are");
if (input.search(/\bk\b/)!=-1) input=input.replace(/\bk\b/,"ok");
if (input.search(/\by\b/)!=-1) input=input.replace(/\by\b/,"why");




if ((input.search("(what is|what's)") != -1) && (input.search("(periodic table)") != -1)) {
document.result.result.value = "Hmmmm, I don't know. Try Google!";
for (var i = 0, len = Periodic_Tables.length; i < len; i++) {
if (Periodic_Tables[i].match('^'+input+'=')) {
document.result.result.value = Periodic_Tables[i].split('=')[1] }
}
return true;}


if (!flagrandom) {
randomnum = [Math.floor(Math.random()*3)]
flagrandom=true;}
message[0] = "Sorry, you stumped me on that one.";  
message[1] = "Sorry, a search of my data base comes up empty."; 
message[2] = "Not sure";
document.result.result.value = message[randomnum]; 
randomnum++
if (randomnum>2){randomnum=0}
return true;}


</script> 




</head> 



<BODY BACKGROUND="FFFFFF" TEXT="#0000cc" LINK="#FFCOOO" ALINK="#FFCC99"
VLINK="#FFC000" marginwidth="0" leftmargin="0" topmargin="0" rightmargin="0">
<Center>
<font size="+3">
ChatterBot
</font>
<br>
<img src="botpix.jpg" border="0" WIDTH="200" HEIGHT="200">
<br>
<form name="result">
<textarea rows=5 cols=40 input type="text" name="result">
</textarea><br>
</form>
</center>
<form name="chat" onSubmit="Parse();return false">
&nbsp;<b>Type here:</b> 
<input type="text" name="input" size="100">
</form>



</body> 
</html>

Upvotes: 0

user2167818
user2167818

Reputation: 1

I would use an array of objects:

Periodic_Tables = [
{Symbol: "h", Element: "Hydrogen"},
{Symbol: "he", Element: "Helium"}
...
]

Then your loop looks like this:

for (i = 0; i < Periodic_Table.length; i++) {
    if (input.indexOf(Periodic_Table[i].Symbol) !== -1) {
        document.result.result.value = Periodic_Table[i].Element;
    }
}

This prevents having to use a regex or a 2d array, and is a little more readable.

Upvotes: 0

argentum47
argentum47

Reputation: 2382

assuming that the question in the chat box ends with the name of the element, u can split the string at the punctuations.(lets say user enters, what is,ag)

function abc(str)
{
String[] parts = str.split("\\W+");
var len=parts.length();
String sub=parts[len-1];
var re=new RegExp("^"+sub+"$","i");
and then use a loop and check the condition 
if(re.test(arr[i])){
document.write(arr[i]);
break;
}
}

Upvotes: 0

user1600124
user1600124

Reputation: 440

First i'd use 2d array to store your periodic tables, so that you don't have to string split every time you want to use it. Instead of

Periodic_Tables=new Array(

"h=Hydrogen", 
"he=Helium", 
"li=Lithium",
"be=Beryllium",
"b=Boron", 
"c=Carbon", 
"n=Nitro­gen", 
"o=Oxygen",
"f=Fluorine", 
"ne=Neon", 
"na=Sodium",
"mg=Magnesium", 
"ag=Silver", 
);

Use

Periodic_Tables = [
["h", "Hydrogen"],
["he", "Helium"],
...

]

Assuming that the question is well formatted, that the symbol "AG" has a space in front and after it. I think you could simple test the input against " AG ", or " ag ", if you make it case insensitive. Including the spaces in the test string will for it to find matches that is a word in it self, instead of part of another word. Pretty use regex has similar abilities, but i am not sure how to do it with regex..

Upvotes: 0

Related Questions