Find anagrams JavaScript jQuery - javascript

Lets Say I have a list like
Dog
dOg
God
doggy
dogg
Zebra
Wood
What I want to do is find all the words in the list regardless of case, or regardless of the actual word. I want to match the letters and take a count. So from above
Dog, dOg, God would all be a match and in this case would return "3" as the count, but doggy, dogg, zebra, wood.. would all be unique and all would return 1 as the count.. Though I know this is possible I don't know where to begin. The anagram concept throws me off a bit. Any ideas?

var words = new Array("Dog", "dOg", "God", "doggy", "dogg","Zebra", "Wood");
var unique = {};
// iterate over all the words
for (i=0; i < words.length; i++) {
// get the word, all lowercase
var word = words[i].toLowerCase();
// sort the word's letters
word = word.split('').sort().join('')
// keep a count of unique combinations
if(unique[word])
unique[word] += 1;
else
unique[word] = 1;
}
// print the histogram
for (u in unique)
document.write(u + ": " + unique[u] + "<br/>")

here's what I came up with... jsfiddle here
$(document).ready(function() {
var mywords = ['Dog', 'dOg', 'God', 'doggy', 'dogg', 'Zebra', 'Wood'];
var finalArr = {};
for (var i = 0; i < mywords.length; i++) {
var temp = mywords[i].toLowerCase();
var letters = temp.split('');
var sorted = letters.sort();
var final = sorted.join("");
if(typeof finalArr[final] != 'undefined'){
finalArr[final] ++;
} else {
finalArr[final] = 1;
}
}
console.log(finalArr);
for(var i in finalArr) {
alert(i + ': ' + finalArr[i]);
document.write(i + ': ' + finalArr[i] + "<br/>");
}
});

Related

How to print top 5 frequently occurring words from a substring

I have some project, with finding the bad words from user. How can i find an a top 5 frequently encountered words from the array of "bad words" in user input string?
I try to do it, but this code doesn't work how i want
const containsAny = (str, substrings) => {
for (var i = 0; i != substrings.length; i++) {
var substring = substrings[i];
if (str.indexOf(substring) != - 1) {
return substring;
}
}
return null;
}
var result = containsAny(textWords, listOfBadWords);
console.log("String was found in substring " + result);
i would like to make it like: word - number of times of use
Try
var filteredArr = topWords.filter(function(item) {
return item[1] != 0;
});
var output = filteredArr.map(function(item) {
return item[0] + " - " + item[1];
}).join(", ");

Reversing words in a string JS without using built in function

Without using the split reverse and join functions, how would one do such a thing?
The Problem Given: Reverse the words in a string
Sample Input: "Hello World"
Sample Output: "World Hello"
<script>
var newString = "";
var theString = prompt("Enter a Phrase that you would like to reverse (Ex. Hello world)");
newString = theString.split(" ").reverse().join(" ")
document.write(newString);
</script>
Arrays can be used like stacks out of the box. And stacks are LIFO, which is what you need.
function reverseWords(str) {
var word, words, reverse;
words = str.match(/(?:\w+)/g);
reverse = '';
while(word = words.pop()) {
reverse += word + ' ';
}
return reverse.trim();
}
reverseWords('hello world');
Or use the call stack as your stack:
function reverseWords(str) {
var result = '';
(function readWord(i = 0) {
var word = '';
if(i > str.length) {
return '';
}
while(str[i] !== ' ' && i < str.length) {
word += str[i];
i++;
}
readWord(++i); // Skip over delimiter.
result += word + ' ';
}());
return result.trim();
}
reverseWords('hello world');
Another idea for reversing the words in a String is using a Stack data structure. Like so:
var newString = "";
var theString = prompt("Enter a Phrase that you would like to reverse (Ex. Hello world)");
var word = "";
var c;
var stack = [];
for (var i = 0, len = theString.length; i < len; i++) {
c = theString[i];
word += c;
if (c == " " || i == (len-1)) {
word = word.trim();
stack.push(word);
word = "";
}
}
while (s = stack.pop()) {
newString += s + " ";
}
console.log(newString);
You could also go fancy and try something like this:
I couldn't come up with a shorter solution.
var newString = "";
var theString = prompt("Enter a Phrase that you would like to reverse (Ex. Hello world)");
theString.replace(/[^\s]*/g, function (value) {
newString = value + ' ' + newString;
});
document.write(newString);
Of the millions of different solutions, the least amount of typing I could come up with involves using lastIndexOf and substring.
var str = "The quick brown fox",
reversed = "",
idx;
while(true) {
idx = str.lastIndexOf(" ")
reversed = reversed + str.substring(idx).trim() + " "
if (idx < 0) break;
str = str.substring(0, idx)
}
reversed.trim() # Oh, yes, trim too
Output:
"fox brown quick The"
The simplest way to do in javascript. Here replace() have /,/g it will replace all comma from the string to space.
var msg = 'Hello world I am Programmer';
var newstr = msg.split(" ").reverse().join().replace(/,/g, ' ');
console.log(newstr)
;

Search for words with specific starts and endings

I asked a pretty detailed question earlier but it got flagged as a duplicate even though it wasn't.
So I will try and explain what I am trying to do as simply as I can. I want to search a text string for words that begin with specific letters such as "mak", "mind" and "mass" (which are in an array) and end with either nothing extra or "e" or "er". That would be in this instance "mak", "make", "maker", "mind", "minde", "minder", "mass", "masse", "masser".
The code I am using only finds the first match for each word in the array, for instance "mak", "mind" and "mass" in the example.
derPro = ['mak','mind', 'mass', ;
for(i = 0; i < derPro.length; i++){
searchTerm = new RegExp(
"\\b" + derPro[i] + "\\b|" +
"\\b" + derPro[i] + "e\\b|" +
"\\b" + derPro[i] + "er\\b,'gi'");
word = testText.match(searchTerm, "gi");
This should work:
var derPro = ['mak','mind', 'mass'];
var searchTerm = new RegExp('\\b((?:' + derPro.join('|') + ')(?:er?)?)\\b', "gi");
//=> /\b((?:mak|mind|mass)(?:er?)?)\b/gi
// now match the regex in a while loop
var matches=[]
while (m = searchTerm.exec('mass maker minde')) matches.push(m[1]);
console.log(matches);
//=> ["mass", "maker", "minde"]
Get the matched group from index 1.
/(\b(mak|mind|mass)(e|er)?\b)/gi
Online demo
This works, i know you asked for a regex, but I thought this would be useful.
var keys = [
'mak',
'mind',
'mass'
];
var test_words = [
'mak',
'make',
'maker',
'mind',
'mass'
];
var matches = [];
for(var i = 0; i < keys.length; i++) {
var key = keys[i];
for(var ii = 0; ii < test_words.length; ii++) {
var test_word = test_words[ii];
if(test_word.substr(0, key.length) == key) {
if( test_word.substr(-1) == 'e' || test_word.substr(-2) == 'er') {
matches.push(test_word);
}
}
}
}
console.log(matches);
// [make, maker, minde]
jsfiddle

Split method and then concatenate

What I need to do is make this function to where it splits each part of the string entered, and then puts pig latin on each word, meaning it adds ay at the end of each word. Here's what I have so far:
function pigLatin(whatWeTitle) {
var alertThis = " ";
var splitArray = whatWeTitle.split(" ");
for ( i = 0; i < splitArray.length; i++) {
alertThis = makeSentenceCase(splitArray[i]) + " ";
var newWord3 = splitArray.substring(1, whatWeTitle.length) + newWord + 'ay';
alert(newWord3);
}
}
Right now, it just takes the first letter of the string and adds it to the end. It doesn't change each word to pig latin, just the whole phrase. I was wondering of anyone could help me with this. THanks.
You need to use [i] to get items of your array :
var word = splitArray[i];
var newWord3 = word.substring(1,word.length) + word[0] + 'ay';
The best, if you want to end up with the whole new sentence, is to change each word an join them at the end :
var splitArray = whatWeTitle.split(" ");
for ( i = 0; i < splitArray.length; i++) {
var word = splitArray[i];
splitArray[i] = word.substring(1,word.length) + word[0] + 'ay';
}
var newSentence = splitArray.join(' ');
alert(newSentence);
If you test a little, you'll see this algorithm doesn't like the dots or comma in your sentence. If you want something stronger, you'd need a regular expression, for example like this :
var newSentence = whatWeTitle.replace(/[^\. ,]+/g, function(word){
return word.slice(1) + word[0] + 'ay';
});
alert(newSentence);
This works by replacing in place the words in the text, using a function to transform each word.
Something like this ?
function pigLatin(whatWeTitle) {
var alertThis = " ";
var splitArray = whatWeTitle.split(" ");
var finalString = "";
for ( i = 0; i < splitArray.length; i++) {
finalString += splitArray[i]+ "ay ";
}
alert(finalString);
}
pigLatin("this is a test");
You probably want to split off the first consonant values and then append them along with 'ay'.
I would use a regex to accomplish this. Here is a JSFiddle showing an example.
First part is split the word
var words = text.split(" ");
Next part is to piglatinify™ each word
words = words.map(function(word){ return pigLatinifyWord(word);});
This is the piglatinify™ function
function pigLatinifyWord(word){
var result;
var specialMatches = word.match(/(\W|\D)+$/);
var specialChars;
if(specialMatches && specialMatches.length >= 0){
var specialIndex = word.indexOf(specialMatches[0]);
specialChars = word.slice(specialIndex);
word = word.substr(0, specialIndex);
}
var i = word.search(/^[^aeiou]/);
if(i >= 0){
result = word.slice(i+1) + word.slice(0, i+1) + "ay";
}
else{
result = word + "ay";
}
if(specialChars){
result += specialChars;
}
return result;
}
Update
JSFiddle example now includes handling for non-word non-digit characters

Highlighting string at multiple occurrences

I'm currently implementing a substring search. From the algorithm, I get array of substrings occurence positions where each element is in the form of [startPos, endPos].
For example (in javascript array):
[[1,3], [8,10], [15,18]]
And the string to highlight is:
ACGATCGATCGGATCGAGCGATCGAGCGATCGAT
I want to highlight (in HTML using <b>) the original string, so it will highlight or bold the string from position 1 to 3, then 8 to 10, then 15 to 18, etc (0-indexed).
A<b>CGA</b>TCGA<b>TCG</b>GATC<b>GAGC</b>GATCGAGCGATCGAT
This is what I have tried (JavaScript):
function hilightAtPositions(text, posArray) {
var startPos, endPos;
var startTag = "<b>";
var endTag = "</b>";
var hilightedText = "";
for (var i = 0; i < posArray.length; i++) {
startPos = posArray[i][0];
endPos = posArray[i][1];
hilightedText = [text.slice(0, startPos), startTag, text.slice(startPos, endPos), endTag, text.slice(endPos)].join('');
}
return hilightedText;
}
But it highlights just a range from the posArray (and I know it is still incorrect yet). So, how can I highlight a string given multiple occurrences position?
Looking at this question, and following John3136's suggestion of going from tail to head, you could do:
String.prototype.splice = function( idx, rem, s ) {
return (this.slice(0,idx) + s + this.slice(idx + Math.abs(rem)));
};
function hilightAtPositions(text, posArray) {
var startPos, endPos;
posArray = posArray.sort(function(a,b){ return a[0] - b[0];});
for (var i = posArray.length-1; i >= 0; i--) {
startPos = posArray[i][0];
endPos = posArray[i][1];
text= text.splice(endPos, 0, "</b>");
text= text.splice(startPos, 0, "<b>");
}
return text;
}
Note that in your code, you are overwriting hilightedText with each iteration, losing your changes.
Try this:
var stringToHighlight = "ACGATCGATCGGATCGAGCGATCGAGCGATCGAT";
var highlightPositions = [[1,3], [8,10], [15,18]];
var lengthDelta = 0;
for (var highlight in highlightPositions) {
var start = highlightPositions[highlight][0] + lengthDelta;
var end = highlightPositions[highlight][1] + lengthDelta;
var first = stringToHighlight.substring(0, start);
var second = stringToHighlight.substring(start, end + 1);
var third = stringToHighlight.substring(end + 1);
stringToHighlight = first + "<b>" + second + "</b>" + third;
lengthDelta += ("<b></b>").length;
}
alert(stringToHighlight);
Demo: http://jsfiddle.net/kPkk3/
Assuming that you're trying to highlight search terms or something like that. Why not replace the term with the bolding?
example:
term: abc
var text = 'abcdefgabcqq';
var term = 'abc';
text.replace(term, '<b>' + term + '</b>');
This would allow you to avoid worrying about positions, assuming that you are trying to highlight a specific string.
Assuming your list of segments is ordered from lowest start to highest, try doing your array from last to first.
That way you are not changing parts of the string you haven't reached yet.
Just change the loop to:
for (var i = posArray.length-1; i >=0; i--) {
If you want to check for multiple string matches and highlight them, this code snippet works.
function highlightMatch(text, matchString) {
let textArr = text.split(' ');
let returnArr = [];
for(let i=0; i<textArr.length; i++) {
let subStrMatch = textArr[i].toLowerCase().indexOf(matchString.toLowerCase());
if(subStrMatch !== -1) {
let subStr = textArr[i].split('');
let subStrReturn = [];
for(let j=0 ;j<subStr.length; j++) {
if(j === subStrMatch) {
subStrReturn.push('<strong>' + subStr[j]);
} else if (j === subStrMatch + (matchString.length-1)){
subStrReturn.push(subStr[j] + '<strong>');
} else {
subStrReturn.push(subStr[j]);
}
}
returnArr.push(subStrReturn.join(''));
} else {
returnArr.push(textArr[i]);
}
}
return returnArr;
}
highlightMatch('Multi Test returns multiple results', 'multi');
=> (5) ['<strong>Multi<strong>', 'Test', 'returns', '<strong>multi<strong>ple', 'results']

Categories