I need to compare titles (which are made of many words)
with a list of bad words. For one word, indexOf works fine.
but when there are many swear words it doesn't.
Can anyone help with this?
var title = "This is my title";
var badwordlist = title.indexOf('fword and other bad words list');
//var badwordlist = title.indexOf('fword');
if ( badwordlist >= 0){
//do something
}
I feel the two answers posted so far are overdoing things
var title = "fword This is a f**king title.",
words = title.split(" "),
badwords = ["fword", "f**king"];
// one of these should do it
var isGood = words.filter(function(a) {
return badwords.indexOf(a) == -1;
});
var isBad = words.filter(function(a) {
return badwords.indexOf(a) != -1;
});
console.log(isBad, isGood);
// if isBad.length>0 then there were swear words in the title
You can use String.prototype.includes() to check if the string contains the bad word:
var title = "fword This is title.";
var badwords = ["fword", "f**k"];
var isbad = badwords.map(function(a) {
return title.includes(a);
});
console.log(isbad);
This is a simple solution, which involves an array, a cycle and a function which coordinates these
var badwords = ['fword', 'uglyword'];
var replacements = ['*word', 'ug***ord'];
function replaceBadwords(title) {
for (var badwordIndex in badwords) {
if (title.indexOf(badwords[badwordIndex]) >= 0) {
title = title.split(badwords[badwordIndex]).join(replacements[badwordIndex]);
}
}
}
However, the word 'assignment' contains an ugly word, which in fact is not ugly. I mean if you read only the first three characters, you will think this is an ugly word. To cope with these exceptions make sure you will not censor these as well.
See this SO question. This will do:
var arr = ['banana', 'monkey banana', 'apple', 'kiwi', 'orange'];
function checker(value) {
var prohibited = ['banana', 'apple'];
for (var i = 0; i < prohibited.length; i++) {
if (value.indexOf(prohibited[i]) > -1) {
return false;
}
}
return true;
}
arr = arr.filter(checker);
console.log(arr);
Obtain arr by splitting your title on space, eg title.split(" ").
Once you do any filtering you can create a filtered title with title = arr.join(" ").
Related
I need to count number of predetermined words (wordlist) in a text. This is what I have done so far:
function frequencies(text, wordlist){
var words = text.split(/\s/);
var freqMap = {};
words.forEach(function(w){
if (!freqMap[w] && wordlist){
freqMap[w] = 0;
}
freqMap[w] += 1;
});
return freqMap;
}
At the moment it counts all the words in given text, how do I make it count only words given in wordlist?
Check word is in given list using Array#indexOf method( or Array#includes method).
function frequencies(text, wordlist) {
var words = text.split(/\s/);
var freqMap = {};
words.forEach(function(w) {
if (wordlist && wordlist.indexOf(w) > -1) { // or wordlist.includes(w)
if (!freqMap[w]) {
freqMap[w] = 0;
}
freqMap[w] += 1;
}
});
return freqMap;
}
This example accounts for some basic punctuation in the text. It will remove said punctuation, split on spaces, then uses reduce to build the object you're wanting.
let wordlist = ['hello', 'bob', 'you', 'later'];
let text = 'hello bob, how are you doing? i hope you are doing well. see you later.';
function frequencies(text, wordlist) {
return text.replace(/(\.|\?|,)/g, '').split(' ').reduce(function(prev, curr) {
if (wordlist.includes(curr)) {
if (prev[curr])
prev[curr]++;
else
prev[curr] = 1;
}
return prev;
}, {});
}
console.log(frequencies(text, wordlist))
I am trying to compare two strings to see if ALL of one of the string's input is also within another string, regardless of order.
So far I have the following code...
What am I doing wrong?
var str1= "rkqodlw"
var str2= "world"
StringScrambler(str1, str2);
function StringScrambler(str1, str2) {
var string1= str1.split("").sort();
console.log(string1);
var string2 = str2.split("").sort();
console.log(string2);
matches = [];
for (i=0; i< string1.length; i++) {
for (j=0; j<string2.length; i++) {
while (j === i) {
matches.push(j);
console.log(matches);
var matchSort = matches.sort();
console.log(matchSort);
if (matchSort === string2) {
return true;
}else {
return false;
}
}
}
}
}
All the answers this far work fine but they will not work for words with double letters in the second string but not in the first (for eg. 'worlld' - notice the double L). The trick is to affect the first word such that it removes the found character(s) so that the same letter is not checked again. Something like this would do the trick:
// Check if the second string's characters are
// found in the first string
function StringScrambler(str1, str2) {
var arr1 = str1.split(''),
arr2 = str2.split(''),
isATrueSubset = true,
indexOfChar;
arr2.forEach(function(char) {
indexOfChar = arr1.indexOf(char);
if (indexOfChar > -1) {
// Remove the character that was found
// to avoid matching against it again
arr1.splice(indexOfChar, 1);
} else {
isATrueSubset = false;
// No need to continue
return;
}
});
console.log(isATrueSubset);
return isATrueSubset;
}
StringScrambler('rkqodlw ', 'world '); // outputs true
StringScrambler('rkqodlw ', 'worlld '); // outputs false
var one = "dlrow";
var two = "world";
var allCharsFound = true;
one.split("").map(function(char) {
if (two.indexOf(char) < 0) {
allCharsFound = false;
}
});
console.log(allCharsFound);
var str1= "rkqodlw";
var str2= "world";
function test($str1, $str2) {
var string2 = str2.split("");
for(var i=0; i<string2.length; i++) {
if (str1.indexOf(string2[i]) == -1) {
return false;
}
}
return true;
}
You can use the following code to do this task:
alert (AllFirstInSecond("world", "rkqodlw"));
alert (AllFirstInSecond("worldz", "rkqodlw"));
function AllFirstInSecond(str1, str2) {
var pos = str1.length - 1;
while (pos >= 0) {
if (str2.indexOf(str1.substr(pos--,1)) == -1) {
return false;
}
}
return true;
}
It simply checks every single character in the first string to see if it's in the second. If not, it returns false.
Only once all have been found does it return true.
There are possibilities for optimisation (every character is checked even if it's a duplicate that's already been checked) but, unless your strings are particularly large, there's probably not much absolute gain to be had.
If str2 is always a subset of str1, then this answer can be used
Compute intersection of two arrays in JavaScript
var arr1 = "rkqodlw".split("");
var arr2 = "world".split("");
var commonValues = arr2.filter(function(value) {
return arr1.indexOf(value) > -1;
});
alert(commonValues.join(""))
This will compare each words of the second string in the first one and if its present it will be added in the mathes array.
var str1= "rkqodlw";
var str2= "world2";
StringScrambler(str1, str2);
function StringScrambler(str1, str2) {
var string2 = str2.split("").sort();
console.log(string2);
matches = [];
for (j=0; j<string2.length; j++) {
if(str1.indexOf(string2[j]) > -1){
matches.push(string2[j]);
console.log(string2[j]);
}
}
console.log(matches);
}
try this:
var str1= "rkqodlw"
var str2= "world"
StringScrambler(str1, str2);
function StringScrambler(str1, str2) {
var string1 = str1.split("").sort();
var string2 = str2.split("").sort();
matches = [];
for (i = 0; i < string1.length; i++) {
if (string2.indexOf(string1[i]) > -1) matches.push(string1[i]);
}
return matches
}
I need to achieve something like the following code, where if a user entered for example (you are bad), it shows an alert. The below code isn't working because it alerts for the words (you are) only without reading what's in badAppend.
var badAppend= ["freak", "ugly", "bad"]
var badWords = [("you are"+badAppend)];
if((badWords)
{
alert("you cannot use this word/sentence");
return false;
}
I'm trying to ahcieve this to avoid doing like the following:
var badWords = ["you are bad", 'you are ugly", "you are freak"];
etc..
I'd really appreciate it much if anyone can help with this. regards.
A more vanilla JavaScript way, on this one you do a "blacklist" check first against an array of "Bad Words" printing only the sentences that are allowed:
var words = document.getElementById('userInput').value.split(" ");
var badWords = ['array', 'of', 'bad', 'words'];
for (i = 0; i < words.length; i++) {
for (ii = 0; ii < badWords.length; ii++) {
var exists = words.indexOf(badWords[ii]);
if (exists != -1) {
words.splice(exists, 1);
}
}
var result = document.getElementById('notInside');
result.innerHTML += words[i];
result.innerHTML += "</br>";
}
I know he's using jQuery but just as another example to do this for other people that might need it. If you need to only display words that ARE in the array just do:
var words = document.getElementById('userInput').value.split(" ");
var badWords = ['array', 'of', 'bad', 'words'];
for (ii = 0; ii < badWords.length; ii++) {
var exists = words.indexOf(badWords[ii]);
if (exists > -1) {
var result = document.getElementById('inside');
result.innerHTML += words[exists];
result.innerHTML += "</br>";
}
}
var newWords = $(badAppend).map(function(item) { return "you are " + item; });
This will give you
newWords = [ "you are freak", "you are ugly", "you are bad" ];
I would do something like this,
var match = $('div.text').text().match(/[yY]ou(('re)|(\sare))\s\w+/g);
if(match){
match = match.map(function(item){
return (item.substring(item.lastIndexOf(" ")+1)).toLowerCase();
});
var match2 = $(match).filter(badWordsArray);
if(match2.length > 0){
console.log('Bad word!');
}else{
console.log('Input is clean!');
}
}else{
console.log('Input is clean!');
}
Change the text selector in the first line to whatever you need.
This will go through all the text that user entered, matches all the words which were followed by one of these:
You are
You're
you are
You are
The match variable will be an array containing all those words, then you can filter it based on your bad word array to see if there was any bad word.
If there is non of those four "you are"s in the code it just logs the input is clean, otherwise it checks for bad words in lowercase.
If you are sure that you just need to match 'you are' exactly, you can replace the regex with this one, it will run faster too. /(you\sare)\s\w+/g
From what I understand, you have a dictionary of bad words and you are trying to prevent user from using those words. In that case, you can do the following:
var containsBadWords = function(words){
var badWords = ['bad', 'ugly', 'freak' /* ...*/];
var badWordCount = 0;
words.forEach(function(word){
if(badWords.indexOf(word)>-1) badWordCount++;
});
return badWordCount;
}
var userWords = 'i am bad you are bad';
var result = containsBadWords(userWords.split(' '));
if(result>0) alert();
can you please tell me how to find the most repeat word in string ?
Example
If input is this
"how do you do"
Output is "do"
var str="how do you do"
function findMostReaptedWord(str){
var res = str.split(" ");
alert(res.length);
var count;
var compareString;
for(var i=0;i<res.length ;i++){
count=0;
compareString=res[i]
for (j=0;i<res.lenth ;j++){
if(compareString==res[j]){
count++
}
}
}
}
alert(findMostReaptedWord(str))
fiddle
http://jsfiddle.net/omjg9v0q/
I gave the idea in a comment. Here it is in code :
function findMostReaptedWord(str){
var counts = {}, mr, mc;
str.match(/\w+/g).forEach(function(w){ counts[w]=(counts[w]||0)+1 });
for (var w in counts) {
if (!(counts[w]<mc)) {
mc = counts[w];
mr = w;
}
}
return mr;
}
A few details :
I use str.match(/\w+/g) for a better decomposition in words. Yours would take anything not a space as a word or part of a word.
counts is a map giving the number of occurrences of each words (i.e. counts["do"] is 2)
using a map avoids doing two levels of loop, which is very slow
Here is my approach
First, separate the words from the string using Regular Expression.
Declare an object as a Map which will help you to find the occurrences of each word. (You can use Map Data Structure!)
Find the most repeated word from that object.
let str = 'How do you do?';
console.log(findMostRepeatedWord(str)); // Result: "do"
function findMostRepeatedWord(str) {
let words = str.match(/\w+/g);
console.log(words); // [ 'How', 'do', 'you', 'do' ]
let occurances = {};
for (let word of words) {
if (occurances[word]) {
occurances[word]++;
} else {
occurances[word] = 1;
}
}
console.log(occurances); // { How: 1, do: 2, you: 1 }
let max = 0;
let mostRepeatedWord = '';
for (let word of words) {
if (occurances[word] > max) {
max = occurances[word];
mostRepeatedWord = word;
}
}
return mostRepeatedWord;
}
Here I give you an approach,
Sort the words first. That way "how do you do" becomes "do do how you".
Iterate the string to count the words that repeat, keep the maximum number of times repeating word in memory while iterating.
-
Mebin
This function may help you
function maxWord (str)
{
var max = 0;
var maxword = '';
var words = str.split(' ');
for(i=0;i<words.length;i++)
{
var count = 0;
var word = '';
for(j=0;j<words.length;j++)
{
if(j !== i && words[i] === words[j])
{
count++;
word = words[i];
}
}
if(count>maxword)
{
max = count;
maxword = word;
}
}
return maxword;
}
maxWord('how do you do'); // returns do
Hello, I'm trying to make a simple matching game in javascript.
If the the user inserts the text president goes crazy in any way that contains every strings in word_tmp, then the word_tmp becomes true, and if he misses one string then it becomes false.
word_tmp = ['president', 'goes', 'crazy'];
// string 1 contains the president, goes and crazy at one string
string1 = 'president goes very crazy'; // should output true
// string 2 doesn't contain president so its false.
string2 = 'other people goes crazy'; // should output false
How can I accomplish this?
Try this:
var word_tmp = ['president', 'goes', 'crazy'];
var string1 = 'president goes very crazy';
var isMatch = true;
for(var i = 0; i < word_tmp.length; i++){
if (string1.indexOf(word_tmp[i]) == -1){
isMatch = false;
break;
}
}
return isMatch //will be true in this case
You can do it with simple reduce call:
word_tmp.reduce(function(res, pattern) {
return res && string1.indexOf(pattern) > -1;
}, true);
The same code, wrapped in a function:
var match_all = function(str, arr) {
return arr.reduce(function(res, pattern) {
return res && str.indexOf(pattern) > -1;
}, true);
};
match_all(string1, word_tmp); // true
match_all(string2, word_tmp); // false
But this solution won't work for you if you want to match whole words. I mean, it will accept strings like presidential elections goes crazy, because president is a part of the word presidential. If you want to eliminate such strings as well, you should split your original string first:
var match_all = function(str, arr) {
var parts = str.split(/\s/); // split on whitespaces
return arr.reduce(function(res, pattern) {
return res && parts.indexOf(pattern) > -1;
}, true);
};
match_all('presidential elections goes crazy', word_tmp); // false
In my example I'm splitting original string on whitespaces /\s/. If you allow punctuation marks then it's better to split on non-word characters /\W/.
var word_tmp = ['president', 'goes', 'crazy'];
var str = "president goes very crazy"
var origninaldata = str.split(" ")
var isMatch = false;
for(var i=0;i<word_tmp.length;i++) {
for(var j=0;j<origninaldata.length;j++) {
if(word_tmp[i]==origninaldata[j])
isMatch = true;
}
}