Formating user input to match stored values - javascript

I have an H3 element that I'm currently using to initialize a game
<h3 id="startGame">Start</h3>
The following is the JavaScript that I've written
In the function formatText() I take what the user has inputted and make the entire string lower case. I then capitalize the first letter of the word so that it matches how the strings are written in the array. In the case where there is actually two words, I then grab the first letter of the second word and capitalize that to match the way the two word strings are written in the array.
In the end when a user inputs what I've asked them to input, it shouldn't matter how they wrote it (in regards to capitalization). All that should matter is that they spelled it right.
However, my problem is that it works for the one word strings but does not capitalize the second word as I intended. Meaning I can enter the one word strings in any manner I wish (spelled correctly of course) and it will resolve to correct. I can even input the two word strings and mess with the capitalization of the first word and it will resolve to correct. However when I do not capitalize the second word it always resolves to incorrect.
The code that I've written to resolve this issue doesn't seem to work and I don't know why.
var nutrients = [
"Vitamin B6",
"Manganese",
"Vitamin C",
"Fiber",
"Potassium",
"Biotin",
"Copper"
];
function memoNutri() {
var pleaseCopy;
var spaceMarker = " ";
var capitalizeSecondWord;
var firstWord;
var secondWord;
var twoWords;
function ask() {
pleaseCopy = prompt("Enter the following into the text field: " + nutrients[i] + ".");
}
function formatText() {
pleaseCopy.toLowerCase();
pleaseCopy = pleaseCopy[0].toUpperCase() + pleaseCopy.substring(1, pleaseCopy.length);
capitalizeSecondWord = pleaseCopy.substring(spaceMarker + 1, spaceMarker + 2).toUpperCase();
firstWord = pleaseCopy.substring(0, spaceMarker);
secondWord = capitalizeSecondWord + pleaseCopy.substring(spaceMarker + 2, pleaseCopy.length);
twoWords = firstWord + spaceMarker + secondWord;
}
for (i = 0; i < nutrients.length; i++) {
ask();
formatText();
if (pleaseCopy === nutrients[i] || twoWords === nutrients[i]) {
alert("You are correct! " + nutrients[i]);
} else {
alert("That is incorrect");
}
}
}
var startGame = document.getElementById('startGame');
startGame.onclick = memoNutri;

Try using this:
var textArr = pleaseCopy.split(" ");
for (var i = 0; i < textArr.length; i++) {
textArr[i] = textArr[i][0].toUpperCase() + textArr[i].substring(1).toLowerCase();
}
var twoWords = textArr.join(" ");
Split the content into an array. Format the text at each index, and the re-join the text.

Related

Filtering List By First Letter

I'm having a bit of trouble filtering my list. I want to filter it to where it checks the first letter of a word the user inputs and if that first letter is the same as the letter from the lettera list.
function checkWords {
var wordsCreated = getText("Input");
for (var i = 0; i < letters.length; i++) {
var firstLetter = letters [i].substring(0,1);
firstUserLetter = wordsCreated.substring(0,1);
if (firstLetter==firstUserLetter) {
// uses appendItem() to add a new item to the word list
appendItem(guessedList, getText("Input"));
setProperty("Input", "text", "");
setText("Output", wordList.join("\n"));
updateScore();
}
}
}
I tried everything but I can't seem to figure out why it's not filtering it to where it only adds the word to the list if the first letter of it corresponds with the random letter.
In the checkWords function, you are looping through the letters list and comparing the first letter of each letter with the first letter of the user's input. However, this is not what you want to do because you only want to compare the first letter of the user's input with the random letter that was generated, not with all the letters in the letters list right?
In the checkWords function, you are using the setText method to set the value of the Output element to the wordList array. This will not work because the setText method expects a string as its argument, but you are passing it an array. To fix this, you can use the .join method to convert the wordList array into a string with each word separated by a newline character, and then pass this string to the setText method.
Something like the code below might work:
}
function checkWords(firstUserLetter) {
var randomLetter = letters[randomNumber(0, letters.Length)];
var wordsCreated = getText("Input");
for (var i = 0; i < letters.Length; i++) {
if (wordsCreated[0] == randomLetter) {
appendItem(wordList, getText("Input"));
setProperty("Input", "text", "");
// convert the wordList array into a string and set it as the value of the Output element
setText("Output", wordList.join("\n"));
}
}
}
var letters = ["a","b","c","d","e","f","g"];
var button = document.querySelector("button");
var resultArray = [];
button.addEventListener("click", function (evt) {
var val = document.querySelector("input").value;
let letter = letters[Math.floor(Math.random()*letters.length)];
console.log("Random letter chosen was " + letter);
if(val.charAt(0) === letter){
resultArray.push(val);
}
console.log("Result list is: " + resultArray);
});
<input type="text" size="10">
<button>submit</button>

Find duplicate two and three keywords in string text

I am basically going to build a "keyword density" function.
The function is going to take text input from a textarea, so a basic string.
Let's say we have the string of My name is not Kevin this is not fun.
What I want to do, is write a function that finds two words groups that are duplicates.
In this example, the result would be is not x2, as the word is not is repeated twice and in the same order.
So instead of finding duplicate single words, for example, we want to find two words together that are duplicates.
Another example: Text string = What is your name? What is your hobby?. The two combinations of groups of words are `What is, so that would count as x2.
So the function is going to find these duplicates inside this text(could be multiple groups), and store it in a way so that I can access it and display it in the UI.
What I have tried:
I am capable of doing this for a single word duplicate in the text, but I am unsure on how to start/go on when it comes to multiple words next to each other.
Any help is greatly appreciated!
Here's a solution for finding 2-word phrases that uses map(), reduce(), Object.entries() and Object.keys(). It's easily extendable to find duplicates of any number of word groups.
let str = "What is your name? What is your hobby?";
let arr = str.split(" ");
let list = Object.entries(arr.reduce((acc, a, index) => {
if (index != 0) acc.push(arr[index - 1] + " " + arr[index])
return acc;
}, []).reduce((acc, a) => {
if (Object.keys(acc).indexOf(a) !== -1) acc[a]++;
else acc[a] = 1;
return acc;
}, {})).map(el => ({
phrase: el[0],
count: el[1]
}));
console.log(list)
That can be done pretty easily in JavaScript. First lets make the string.
let testString = "The dog jumps and the dog barks just some dummy text there.
Now if want to get all the words, we can use testString.split(" ") this will split the string and return an array. Now just count how many times they occur.
Here's the code in action
let testString = "the dog jumps and the dog barks";
let testArray = testString.split(" ")
testArray.sort() //this will sort the array
function count() {
let current = null;
let cnt = 0;
for (var i = 0; i < testArray.length; i++) {
if (testArray[i] != current) {
if (cnt > 0) {
document.write(current + ' - ' + cnt + '<br>');
}
current = testArray[i];
cnt = 1;
} else {
cnt++;
}
}
if (cnt > 0) {
document.write(current + '-' + cnt);
}
}
count();
if this solution is your desired answer then please mark this answer by clicking the tick on the left.
Thank you!

Javascript replace already replaced text

I have two textareas written in HTML like this:
<textarea id="checked-words"></textarea>
<br />
<textarea id="words" onkeyup="displayColoredText()"></textarea>
<div id="text-to-insert"></div>
(into the div element, I will insert text, using JavaScript)
My task is to write into the div section the text from the second textarea and make red the occurrences of strings from the first textarea.
Example
If the first textarea contains the following words: aaa, aab and the second contains aaab, all of the characters have to be red. If the second one contains abaa, none of the characters will be red in the div section.
Here is my JavaScript function which displays and colorize the text:
function displayColoredText() {
//Displays the colored text below the second textarea
//Find the two textareas
var firstTextArea = document.getElementById('checked-words');
var secondTextArea = document.getElementById('words');
//Split by spaces
var checkedWords = firstTextArea.value.split(" ");
var text = secondTextArea.value.split(" ");
var textToInsert = secondTextArea.value;
for(i in checkedWords) {
console.log(checkedWords.length);
textToInsert = textToInsert.replace(new RegExp(checkedWords[i], 'g'), '<span class="insertRed">' + checkedWords[i] + '</span>');
}
document.getElementById('text-to-insert').innerHTML = textToInsert;
}
My problem is, that an already replaced text won't be considered, for example, if the first textarea contains aaa and aab and if the second one contains aaab, only the first three characters will be red, instead of the whole string. How can I resolve this?
EDIT: Screenshot of the problem
Your original input from the second text area is pure text, not HTML, so this is the "state" of the data you want to do this in.
This would be my way of implementing it as mentioned in comments, recording which positions have a match first, and then simply looping over all characters in the end to wrap them in a span each:
function displayColoredText() {
//Displays the colored text below the second textarea
//Find the two textareas
var firstTextArea = document.getElementById('checked-words');
var secondTextArea = document.getElementById('words');
//Split by spaces
var checkedWords = firstTextArea.value.split(" ");
var text = secondTextArea.value;
// empty array with keys 0 to length-1 set to undefined
var markedMatches = new Array(secondTextArea.value.length);
for (var i = 0, l = checkedWords.length; i < l; ++i) {
var checkedWord = checkedWords[i],
start = 0,
matchPos;
// check for match from current starting position
while ((matchPos = text.indexOf(checkedWord, start)) !== -1) {
// mark positions from current match start to that plus length of match
for (var k = matchPos, m = matchPos + checkedWord.length; k < m; ++k) {
markedMatches[k] = true;
}
// advance starting position to continue searching
start = matchPos + 1;
}
}
var textToInsert = '';
for (var i = 0, l = text.length; i < l; ++i) {
// wrap in span if markedMatches contains true at this position
textToInsert += (markedMatches[i] ? '<span class="match">' + text[i] + '</span>' : text[i]);
}
document.getElementById('text-to-insert').innerHTML = textToInsert;
}
https://jsfiddle.net/t9xjzkaw/
As I said, you could get more sophisticated in collecting the matches as intervals, or putting multiple adjoining matching characters into a single span element, instead of wrapping each one on its own ... but this does the basic job.
Your problem is how your strings get replaced. Your first string is 'aaa aab'. After replacing for 'aaa' in 'aaab', you get '<span class="insertRed">aaa</span>b'. Trying to find 'aab' in this string will come up with no results. You have to replace from your original string and somehow combine the two. I'm not sure how to do this, but I hope this sets you on the right track.
EDIT:
I think this will work:
Instead of replacing the text in the string, place the beginning coordinate in an array and the end coordinate in a second array. Keep doing this for every word found. Then at all of the beginning coordinates, insert the string '<span class="insertRed">'. At all of the end coordinates, insert the string '<span>'. Here is the JS:
function displayColoredText() {
//Displays the colored text below the second textarea
//arrays with coordinates
var beginnings = [];
var ends = [];
//Find the two textareas
var firstTextArea = document.getElementById('checked-words');
var secondTextArea = document.getElementById('words');
//Split by spaces
var checkedWords = firstTextArea.value.split(" ");
var text = secondTextArea.value.split(" ");
var textToInsert = firstTextArea.value;
for(i in checkedWords) {
console.log(checkedWords.length);
if (firstTextArea.value.indexOf(checkedWords[i]) != -1) {
beginnings.push(firstTextArea.value.indexOf(checkedWords[i]));
ends.push(firstTextArea.value.indexOf(checkedWords[i]) + checkedWords[i].length);
}
}
beginnings.sort(function(a, b){return b-a});
ends.sort(function(a, b){return b-a});
for (b in beginnings) {
textToInsert = textToInsert.slice(0, ends[b]) + "</span>" + textToInsert.slice(ends[b]);
textToInsert = textToInsert.slice(0, beginnings[b]) + '<span class="insertRed">' + textToInsert.slice(beginnings[b]);
}
document.getElementById('text-to-insert').innerHTML = textToInsert;
}
This code is untested, so tell me if something doesn't work and I will change it. Basically, what I am doing is instead of replacing occurrences, I find them first, place them in arrays, and insert the correct text at those coordinates. I hope this helps!

Split sentence by space mixed up my index

I'm facing some problem while trying to send text to some spelling API.
The API return the corrections based on the words index, for example:
sentence:
"hello hoow are youu"
So the API index the words by numbers like that and return the correction based on that index:
0 1 2 3
hello hoow are youu
API Response that tell me which words to correct:
1: how
3: you
On the code I using split command to break the sentence into words array so I will be able to replace the misspelled words by their index.
string.split(" ");
My problem is that the API trim multiple spaces between words into one space, and by doing that the API words index not match my index. (I would like to preserve the spaces on the final output)
Example of the problem, sentence with 4 spaces between words:
Hello howw are youu?
0 1 2 3 4 5 6 7
hello hoow are youu
I thought about looping the words array and determine if the element is word or space and then create something new array like that:
indexed_words[0] = hello
indexed_words[0_1] = space
indexed_words[0_2] = space
indexed_words[0_3] = space
indexed_words[0_4] = space
indexed_words[0_5] = space
indexed_words[0_6] = space
indexed_words[0_7] = space
indexed_words[1] = how
indexed_words[2] = are
indexed_words[3] = you?
That way I could replace the misspelled words easily and than rebuild the sentence back with join command but the problem but the problem that I cannot use non-numeric indexes (its mixed up the order of the array)
Any idea how I can keep the formatting (spaces) but still correct the words?
Thanks
in that case you have very simple solution:L
$(document).ready(function(){
var OriginalSentence="howw are you?"
var ModifiedSentence="";
var splitstring=OriginalSentence.split(' ')
$.each(splitstring,function(i,v){
if(v!="")
{
//pass this word to your api and appedn it to sentance
ModifiedSentence+=APIRETURNVALUE//api return corrected value;
}
else{
ModifiedSentence+=v;
}
});
alert(ModifiedSentence);
});
Please review this one:
For string manipulation like this, I would highly recommend you to use Regex
Use online regex editor for faster try and error like here https://regex101.com/.
here I use /\w+/g to match every words if you want to ignore 1 or two words we can use /\w{2,}/g or something like that.
var str = "Hello howw are youu?";
var re = /\w+/g
var words = str.match(re);
console.log("Returning valus")
words.forEach(function(word, index) {
console.log(index + " -> " + word);
})
Correction
Just realize that you need to keep spacing as it is, please try this one:
I used your approach to change all to space. create array for its modified version then send to your API (I dunno that part). Then get returned data from API, reconvert it back to its original formating string.
var ori = `asdkhaskd asdkjaskdjaksjd askdjaksdjalsd a ksjdhaksjdhasd asdjkhaskdas`;
function replaceMeArr(str, match, replace) {
var s = str,
reg = match || /\s/g,
rep = replace || ` space `;
return s.replace(reg, rep).split(/\s/g);
}
function replaceMeStr(arr, match, replace) {
var a = arr.join(" "),
reg = match || /\sspace\s/g,
rep = replace || " ";
return a.replace(reg, rep);
}
console.log(`ori1: ${ori}`);
//can use it like this
var modified = replaceMeArr(ori);
console.log(`modi: ${modified.join(' ')}`);
//put it back
var original = replaceMeStr(modified);
console.log(`ori2: ${original}`);
Updated
var str = "Hello howw are youu?";
var words = str.split(" ");
// Getting an array without spaces/empty values
// send it to your API call
var requestArray = words.filter(function(word){
if (word) {
return word;
}
});
console.log("\nAPI Response that tell me which words to correct:");
console.log("6: how\n8: you");
var response = {
"1": "how",
"3": "you"
}
//As you have corrected words index, Replace those words in your "requestArray"
for (var key in response) {
requestArray[key] = response[key];
}
//now we have array of non-empty & correct spelled words. we need to put back empty (space's) value back in between this array
var count = 0;
words.forEach(function(word, index){
if (word) {
words[index] = requestArray[count];
count++;
}
})
console.log(words);
Correct me, if i was wrong.
Hope this helps :)
Try this JSFiddle
, Happy coding :)
//
// ReplaceMisspelledWords
//
// Created by Hilal Baig on 21/11/16.
// Copyright © 2016 Baigapps. All rights reserved.
//
var preservedArray = new Array();
var splitArray = new Array();
/*Word Object to preserve my misspeled words indexes*/
function preservedObject(pIndex, nIndex, title) {
this.originalIndex = pIndex;
this.apiIndex = nIndex;
this.title = title;
}
/*Preserving misspeled words indexes in preservedArray*/
function savePreserveIndexes(str) {
splitArray = str.split(" ");
//console.log(splitArray);
var x = 0;
for (var i = 0; i < splitArray.length; i++) {
if (splitArray[i].length > 0) {
var word = new preservedObject(i, x, splitArray[i]);
preservedArray.push(word);
x++;
}
}
};
function replaceMisspelled(resp) {
for (var key in resp) {
for (var i = 0; i < preservedArray.length; i++) {
wObj = preservedArray[i];
if (wObj.apiIndex == key) {
wObj.title = resp[key];
splitArray[wObj.originalIndex] = resp[key];
}
}
}
//console.log(preservedArray);
return correctedSentence = splitArray.join(" ");
}
/*Your input string to be corrected*/
str = "Hello howw are youu";
console.log(str);
savePreserveIndexes(str);
/*API Response in json of corrected words*/
var apiResponse = '{"1":"how","3":"you" }';
resp = JSON.parse(apiResponse);
//console.log(resp);
/*Replace misspelled words by corrected*/
console.log(replaceMisspelled(resp)); //Your solution

Javascript split array

I have a JavaScript array which contain the staff's Chinese and English names.
Example:
XXX MA Yo-Yo
Where XXX represents the Chinese name: 馬友友.
I want to split this into two parts by using the 1st space " " as an indicator.
for (i = 0; i < /* ... */)
{
w_temp = arr[i];
w_name = w_temp[1].split(' ', 1);
/* ... */
}
w_name[0] successfully returns 馬友友. But w_name[1] returns undefined, which cannot return MA Yo-Yo.
How can I split it into two parts?
Replace your existing w_name = ... line with something like this:
w_name = w_temp[1].split(' ');
w_name = [w_name[0], w_name.slice(1).join(' ')];
The ,1 you had earlier meant to stop parsing as soon as it came to the first space. This is not what you want; you want the part before the first space as one item and the part after as another. The new code parses all of the elements. After that, it sets it to an array consisting of:
The already-existing first element, and
The parts after the first element re-joined.
You have
split(' ', 1)
The 1 means to return at most one part. You should just ommit that or change it to two if thats what you need.
Because you invoke split method with limit = 1, then w_name has only 1 item.
In addition, yours input string has 2 whitespace, therefore, if you use split without limit parameter, w_name will contains 3 items ('XXX', 'CHAN', and 'Tai-Man').
I think you should use this:
var idx = str.indexOf(' ');
if (idx != -1) {
var cn_name = str.substring(0, idx);
var en_name = str.substring(idx + 1);
}
Try this
for (var i = 0; i < arr.length; i++) {
var w_temp = arr[i];
// assuming w_temp contains an array where the second item
// is the full name string
var parts = w_temp[1].match(/^(.+?) (.+)$/);
var cn_name = parts[1];
var en_name = parts[2];
}

Categories

Resources