PDA

View Full Version : Confirm/Searching/Counting an Array



Psychonaut Cid
Oct 28th, 2009, 03:45 PM
I feel stupid for asking a question about searching arrays, when there's a very similar thread that has been answered just recently on the first page; however, I'm still having trouble contemplating my own scenario.

Basically, my program prompts the user for the length of the array and then asks the user to fill the array with words.

Here is where I need help:

I want to confirm if the user wants to search the array for those words. If so, the user will then be prompted to enter the word he wishes to search for; if found, the location of that word will be reported and the number of times the word has been searched for will be kept track of in a separate array.

Here is what I have so far:


/* -- phase 3 ------------------------------------------------------
search for words the user asks for
*/
// search variables
var response;
var search;


while (true) {
// confirmation protocol
response = confirm("Do you wish to search the lexicon for a word?")
if (response) {
search = prompt("What word would you like to search for?");
// alert("search");
}
else {
alert("Thank you for wasting my time.");
break;
}

// begin search protocol
for (i=0; i<words.length; i++) {
if (search==words[i]) { alert("Word found at" +i+);}
} // end for loop

else {alert("word not found.");}


// counter array/accumulator
var hits = new Array(words.length);
hits[i] = 0;

for (i=0; i<words.length; i++) {
if (words[i] == search) {
hits[i] = hits[i] + 1;
alert("This word has been searched for " +hits[i]+ "times.");
}
} // end for loop




} // end while

The problem with my search seems to be that the search is parsed through the for loop; if it finds the word it alerts me that it was found at i location, but then it continues through and sees that the search does not equal the other values in the array and reports it's not found as well.

My counter array is completely off, and I'm really at a loss to figure it out. I can see that the problem might be that each new search resets the hits[i] to equal 0, so no matter how many times a word is searched for, it returns a count of 1. I really want this array to track the number of hits for each word searched for, but have no clue why it's not working.

Thanks for any help I can get; and please, feel free to critique my coding style, I definitely need to improve.

ckeyrouz
Oct 28th, 2009, 04:00 PM
replace the chunk of code you have posted in the previous post with this:

/* -- phase 3 ------------------------------------------------------
search for words the user asks for
*/
// search variables
var response;
var search;
var hits = new Array(words.length);
//initializing all hits to 0 before entering the loop
for(var k=0;k<hits.length; k++)
{
hits[k] = 0;
}

while (true) {
// confirmation protocol
response = confirm("Do you wish to search the lexicon for a word?")
if (response) {
search = prompt("What word would you like to search for?");
// alert("search");
}
else {
alert("Thank you for wasting my time.");
break;
}

// begin search protocol
for (i=0; i<words.length; i++) {
if (search==words[i])
{
alert("Word found at" +i+);
break;//exits the for loop
}
} // end for loop

else {alert("word not found.");}


// counter array/accumulator



for (i=0; i<words.length; i++) {
if (words[i] == search) {
hits[i] = hits[i] + 1;
alert("This word has been searched for " +hits[i]+ "times.");
}
} // end for loop




} // end while

itsallkizza
Oct 28th, 2009, 04:12 PM
JS only:


function arr_index_of(arr,search,strict)
{
for (var i=0;i<arr.length;i++)
{
if (search == arr[i] && (!strict || search === arr[i])) return i;
}
return -1;
}

var words = ["apple","banana","pear","columbo"];
var words_searched = new Object();

function phase3()
{
var response = confirm("Do you wish to search the lexicon for a word?");
if (response)
{
var search = prompt("What word would you like to search for?");
words_searched[search] = words_searched[search] ? words_searched[search]+1 : 1;
var index_of_word = arr_index_of(words,search);
if (index_of_word != -1) alert('Word found at location '+index_of_word+'.\n"'+search+'" has been searched for '+words_searched[search]+' times.');
else alert('Word not found.\n"'+search+'" has been searched for '+words_searched[search]+' times.');;
phase3();
}
else alert("Thank you for wasting my time.");
}
phase3();



Copy and paste this into an empty .html file to test:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Test</title>
<script type="text/javascript">
// <![CDATA[

function arr_index_of(arr,search,strict)
{
for (var i=0;i<arr.length;i++)
{
if (search == arr[i] && (!strict || search === arr[i])) return i;
}
return -1;
}

var words = ["apple","banana","pear","columbo"];
var words_searched = new Object();

function phase3()
{
var response = confirm("Do you wish to search the lexicon for a word?");
if (response)
{
var search = prompt("What word would you like to search for?");
words_searched[search] = words_searched[search] ? words_searched[search]+1 : 1;
var index_of_word = arr_index_of(words,search);
if (index_of_word != -1) alert('Word found at location '+index_of_word+'.\n"'+search+'" has been searched for '+words_searched[search]+' times.');
else alert('Word not found.\n"'+search+'" has been searched for '+words_searched[search]+' times.');;
phase3();
}
else alert("Thank you for wasting my time.");
}

window.onload = function()
{
phase3();
}

// ]]>
</script>
</head>
<body>

</body>
</html>

Stooshie
Oct 28th, 2009, 06:10 PM
This gives me an idea.

JavaScript Tennis anyone? :-)

itsallkizza
Oct 28th, 2009, 07:10 PM
dangit ckey you beat me to it. mines still better though ;)

ckeyrouz
Oct 28th, 2009, 07:18 PM
I don't deny it.
But you haven't seen my solution yet.

All I did was make some changes in the original code so the OP's solution work.

Cheers.

Psychonaut Cid
Oct 28th, 2009, 08:21 PM
Definitely appreciate the help guys. Establishment of the hits array before the while loop... so simple, yet genius.

Another quick question, how can I insert an alert statement for the following scenario:

User confirms search of array, word search prompt appears, but then user decides to cancel that prompt.

My issue here, I guess, is determining what value is entered into the search var for such a condition. Is it null, undefined, or what?

if (search == ????) {alert("Guess you changed your mind.")};

rnd me
Oct 29th, 2009, 01:10 AM
User confirms search of array, word search prompt appears, but then user decides to cancel that prompt.

My issue here, I guess, is determining what value is entered into the search var for such a condition. Is it null, undefined, or what?


if (search === null){alert("Guess you changed your mind.")};

Psychonaut Cid
Oct 29th, 2009, 03:06 AM
Thanks again.

Two more questions as I wrap this program up.

1. How can I prevent anything but letters from being entered into the following prompt:


for (i=0; i<numWords; i++) {
words[i] = prompt("Please enter a desired word to be stored into the dictionary.");
} // end array load for loop

Which is to say, if the user enters anything but letters he will be alerted and redirected to the original prompt, and his input ignored. Also need something to say when the input is null.

I figured all that data verification out for the previous input in my first post, but trying to fit the validation around this prompt statement in the for loop is tricking me up. I've tried establishing a while loop around the for loop and breaking them in various places, but I always end up with an infinite loop.

2. Finally, I have data verification at the beginning of my program :


if (numWords <= 0 || isNaN(numWords) || numWords != Math.floor(numWords)) {
alert("Unfortunately for your simple mind, only positive integers can be used to determine lexicon size. Please, try again.");
}

The above works fine, except when 0 is entered. It delivers the alert statement but continues to run the rest of the program, since I guess an array size of 0 is valid, whereas the other bits of that verification produce invalid array sizes.

My question then is how can I force those conditions to not run the program.

EDIT: Figured out the problem I had in 2. A simple return; line was enough.

Philip M
Oct 29th, 2009, 09:08 AM
1. How can I prevent anything but letters from being entered into the following prompt:


for (i=0; i<numWords; i++) {
words[i] = prompt("Please enter a desired word to be stored into the dictionary.","");
words[i] = words[i].replace(/\s+/g,""); //strip all spaces
words[i] = words[i].toLowerCase(); // make lowercase
if ((/[^a-z]/.test(words[i])) || (words[i].length < 2) || (words[i].length >20)) { // must be alpha, not a single letter, max 20 letters
alert ("That is not a valid entry!");
i--;
}
}

Quizmaster: According to legend, who shot an apple off the top of his son's head?
Contestant: Was it Isaac Newton?

Old Pedant
Oct 29th, 2009, 09:16 AM
My variation on that (see this thread: http://www.codingforums.com/showthread.php?t=180237 ) would be:


var reWord = /^[a-z]{2,20}$/i ; // philip forgot the $
for (i=0; i<numWords; i++)
{
while ( true )
{
word = prompt("Please enter a desired word to be stored into the dictionary.","");
word = word.replace(/\s+/g,""); //strip all spaces
if ( reWord.test(word) ) break;
alert("Invalid: words must be 2 through 20 letters only...try again");
}
words[i] = word;
}

Philip M
Oct 29th, 2009, 09:40 AM
var reWord = /^[a-z]{2,20}$/i ; // philip forgot the $


No he didn't! [^a-z] means not anything a-z. $ means end of string.
Your script requires a-z. Mine rejects anything not a-z.

I agree that an upper limit on number of letters should be set. For dictionary use the word should be lower case. Your script requires it to be entered in lower case - mine transforms it to lower case.

As always - several different ways to skin a cat.

If the user presses "Cancel" an error is thrown. So here is my revised script which in effect disables the Cancel button (in Old Pedant's script if the user presses Cancel all his previous entries are lost):-



var words = [];
var numWords = 3;

for (i=0; i<numWords; i++) {
words[i] = prompt ("Please enter a desired word to be stored into the dictionary.","");
if (words[i]) {
words[i] = words[i].replace(/\s+/g,""); //strip all spaces
words[i] = words[i].toLowerCase(); // make lowercase
if (!/^[a-z]{2,20}$/.test(words[i])) { // must be alpha, min 2 letters, max 20 letters
//if ((/[^a-z]/.test(words[i])) || (words[i].length < 2) || (words[i].length >20)) { // same thing as above
alert ("That is not a valid entry!");
i--;
}
}
else {i--}
}

Old Pedant
Oct 29th, 2009, 07:18 PM
It was late. Blame it on failing eyesight. Blame it on being really late at night. Blame it on... Well, anything but senility <sigh/>.

DOH.