Finding the index of several identical words - javascript

I have a laTeX string like this
let result = "\\frac{x}{2}+\\frac{3}{x}";
I want to find the index of "frac"s in the string and put them in a array then I want to find the first '}' char after "frac" and replace it with "}/" and finally remove "frac" from the string.
I used this block of code but it just work correctly when we have one "frac"
let result = "\\frac{x}{2}+\\frac{3}{x}";
if (result.indexOf("frac") != -1) {
for (let i = 0; i < result.split("frac").length; i++) {
let j = result.indexOf("frac");
let permission = true;
while (permission) {
if (result[j] == "}") {
result = result.replace(result[j], "}/")
permission = false;
}
j++;
}
result = result.replace('frac', '');
}
}
console.log(result)
OUTPUT: \\{x}//{2}+\\{3}{x}
Could anyone help me to improve my code?

Something like this?
frac(.+?)}
is the literal frac followed by a capture group that will capture one or more of anything .+ until a } and replace it with that anything plus a }/
Using the function replacement to grab index and replace
let result = "\\frac{x}{2}+\\frac{3}{x}";
let pos = [];
const newRes = result.replace(/frac(.+?)}/g,function(match, found, offset,string) {
console.log(match,found,offset,string)
pos.push(offset)
return `${found}/`; // return the found string with the added slash
})
console.log(pos)
console.log(newRes)
Older answer using two sets of code
let result = "\\frac{x}{2}+\\frac{3}{x}";
let re = /frac/gi, res, pos = [];
while ((res = re.exec(result))) {
pos.push(res.index);
}
const newRes = result.replace(/frac(.+?)}/g,"$1}/")
console.log(pos)
console.log(newRes)

Related

Getting string in quotes in javascript

How may I write a function to get all the strings in quotes from a string? The string may contain escaped quotes. I've tried regex but as regex does not have a state like feature, I wasn't able to do that. Example:
apple banana "pear" strawberries "\"tomato\"" "i am running out of fruit\" names here"
should return an array like ['pear', '"tomato"', 'i am running out of fruit" names here']
Maybe something with split can work, though I can't figure out how.
I solved this problem using the following function:
const getStringInQuotes = (text) => {
let quoteTogether = "";
let retval = [];
let a = text.split('"');
let inQuote = false;
for (let i = 0; i < a.length; i++) {
if (inQuote) {
quoteTogether += a[i];
if (quoteTogether[quoteTogether.length - 1] !== '\\') {
inQuote = false;
retval.push(quoteTogether);
quoteTogether = "";
} else {
quoteTogether = quoteTogether.slice(0, -1) + '"'
}
} else {
inQuote = true;
}
}
return retval;
}
Try this:
function getStringInQuotes(text) {
const regex = const regex = /(?<=")\w+ .*(?=")|(?<=")\w+(?=")|\"\w+\"(?=")|(?<=" )\w+(?=")|(?<=")\w+(?= ")/g
return text.match(regex);
}
const text = `apple banana "pear" strawberries "\"tomato\"" "i am running out of fruit\" names here"`;
console.log(getStringInQuotes(text));

Find how many repetetive letters there are in the text

My goal is to get the result of 3 since in "aaBbCChr" letters a,b and c are repeating themselves. I've made this function, everything looks right, but it just doesn't work properly.
function duplicateCount(text) {
let lettersArray = text.split("");
let duplicateResult = 0;
lettersArray.map(function(letter) {
let regexLetter = new RegExp(letter, "gi");
let matchesCount = text.match(regexLetter).length;
if (matchesCount > 1) {
duplicateResult + 1;
} else {};
});
return duplicateResult;
};
alert(duplicateCount("aaBbCChr"));
Issues with your code:
duplicateResult + 1; This doesn't change the value of duplicateResult. You need to use a statement that actually increases its value like duplicateResult += 1;
lettersArray also contains the letters multiple times. First remove the duplicates there before looking whether they appear multiple times in the string or you will count them multiple times. See Get all unique values in a JavaScript array (remove duplicates)
Make all lowercase letters in lettersArray so that you don't count the same letter twice when it appears in lowercase and uppercase.
This code works
function duplicateCount(text) {
let lettersArray = text.toLowerCase().split("");
let duplicateResult = 0;
function onlyUnique(value, index, self) {
return self.indexOf(value) === index;
}
lettersArray = lettersArray.filter( onlyUnique );
lettersArray.map(function(letter) {
let regexLetter = new RegExp(letter, "gi");
let matchesCount = text.match(regexLetter).length;
if (matchesCount > 1) {
duplicateResult += 1;
} else {};
});
return duplicateResult;
};
alert(duplicateCount("aaBbCChr"));
Another approach is to invert the logic used in Get all unique values in a JavaScript array (remove duplicates) to use filter to filter out all those characters that appear multiple times and then count those.
function duplicateCount2(text) {
let lettersArray = text.toLowerCase().split("");
let duplicateResult = 0;
function onlyNonUnique(value, index, self) {
return self.indexOf(value) !== index;
}
lettersArray = lettersArray.filter(onlyNonUnique);
duplicateResult = lettersArray.length;
return duplicateResult;
};
alert(duplicateCount2("aaBbCChr"));
It is far easier to do it with changing the structure to an object
const reduced = [...myChars].reduce((map, charCaseSensitive) => {
const char = charCaseSensitive.toLowerCase();
if(map[char]) map[char]++;
else map[char] = 1;
return map;
}, {};
const numberOfRepeatedChars = Object.values(reduced).filter(v => v > 1).length;
Here's the version making minimal changes to your code. You need to lowercase the string here so that the same letter in caps is not counted again.
function duplicateCount(text) {
let lettersArray = text.toLowerCase().split("");
let duplicateResult = 0;
let set = new Set();
lettersArray.map(function(letter) {
let regexLetter = new RegExp(letter, "gi");
let matchesCount = text.match(regexLetter).length;
if (!set.has(letter) && matchesCount > 1) {
set.add(letter);
duplicateResult += 1;
} else {};
});
return duplicateResult;
};
alert(duplicateCount("aaBbCChr"));
As mentioned in other comments, your problem is that you're resetting duplicateResult = 1 to a duplicate result. You probably meant to do duplicateResult += 1, but even that is incorrect because you said that you only want to get repeated characters, so no matter how many times a letter repeats, if it repeats at all, you only count it once.
My approach would be to count the characters in the string in an object (key is the letter, value is the occurrence count) and afterwards count the number of keys that have an occurrence count of more than 1.
function duplicateCount(text) {
const isValidLetter = /[a-z]/i; // a through z, case insensitive
const charCounts = text.split('').reduce(function(acc, char) {
if(isValidLetter.test(char)) {
char = char.toLowerCase();
if(acc[char] === undefined) {
acc[char] = 1;
} else {
acc[char] += 1;
}
}
return acc;
}, {});
return Object.keys(charCounts).filter(c => charCounts[c] > 1).length;
}
alert(duplicateCount('aaBbCChr'));

how to convert passed string to Camel Case

Hi I'm working on a problem that requires me to 'returns the passed string convertedToCamelCase'
I tried doing it like this
let wordsArr = words.toLowerCase().split(" ")
for (let i = 1; i<wordsArr.length; i++){
wordsArr[i] = wordsArr[i].charAt(0).toUpperCase()
wordsArr.slice(1)
}
return wordsArr.join("")
but that doesnt seem to work and now im stuck
Something like this should work if it doesn't contain punctuation
let camelot = "I have to push the pram a lot";
const makeCamel = s => {
let camelArray = s.toLowerCase().split(' ')
let newArray = [camelArray[0]]
for (let i in camelArray) {
if (i >= 1) {
let capLetter = camelArray[i][0].toUpperCase()
let rest = camelArray[i].slice(1);
let newWord = capLetter + rest
newArray.push(newWord);
}
}
return newArray.join('');
}
makeCamel(camelot)

How can I match a word inside of a string to word in a list EXACTLY?

I have been playing around with a pokemon API for a couple of days.
I have an array with all pokemon listed and have a string that looks something like this '<#user_id pidgeotto>'
I would like to check this string, against an array and get that EXACT name
My issue is that I ALSO get things that would be included, like pidgeot.
How can I match the array exactly to the string and ONLY log the one name?
let pokemonArray = ["pidgeot", "pidgeotto", "charizard", "goldeen"];
let y = '<#user_id> pidgeotto';
function handleMessage(message) {
for (let i = 0; i <= message.length; i++) {
if (y.includes(message[i])) {
console.log(message[i])
}
}
}
handleMessage(pokemonArray);
No errors, just not getting the result I am looking for.
Split the y string at the space and see if second part is exact using === comparison
let pokemonArray = ["pidgeot", "pidgeotto", "charizard", "goldeen"];
let y = '<#user_id> pidgeotto';
let yName = y.split(' ')[1];
function handleMessage(message) {
for (let i = 0; i <= message.length; i++) {
if (message[i] === yName ) {
console.log(message[i])
}
}
}
handleMessage(pokemonArray);
you could do it by this way to avoid the first element in PokemonArray
let pokemonArray = ["pidgeot", "pidgeotto", "charizard", "goldeen"];
let y = '<#user_id> pidgeotto';
function handleMessage(message) {
for(let i = 0; i <= message.length; i++) {
let splitedY = y.split(message[i])
if(splitedY.length > 1 && splitedY[1] !== "") {
console.log(message[i])
}
}
}
handleMessage(pokemonArray);
Here is the one liner for this:
const match = pokemonArray.find(pokemon => new RegExp(`\\b${pokemon}\\b`, `i`).test(y));
Simply use array find method and match your string using regex.
Hope this helps :)

Get Full string using part of a given string

var string = "Let's say the user inputs hello world inputs inputs inputs";
My input to get the whole word is "put".
My expected word is "inputs"
Can anyone share your solution?
Thanks in advance
One way to do what you're asking is to split the input string into tokens, then check each one to see if it contains the desired substring. To eliminate duplicates, store the words in an object and only put a word into the result list if you're seeing it for the first time.
function findUniqueWordsWithSubstring(text, sub) {
var words = text.split(' '),
resultHash = {},
result = [];
for (var i = 0; i < words.length; ++i) {
var word = words[i];
if (word.indexOf(sub) == -1) {
continue;
}
if (resultHash[word] === undefined) {
resultHash[word] = true;
result.push(word);
}
}
return result;
}
var input = 'put some putty on the computer output',
words = findUniqueWordsWithSubstring(input, 'put');
alert(words.join(', '));
A RegEx and filter to remove duplicates;
var string = "I put putty on the computer. putty, PUT do I"
var uniques = {};
var result = (string.match(/\b\w*put\w*\b/ig) || []).filter(function(item) {
item = item.toLowerCase();
return uniques[item] ? false : (uniques[item] = true);
});
document.write( result.join(", ") );
// put, putty, computer

Categories

Resources