let str = "i am writing an algorithm.";
//function to count alphabets
const alphabet_count = (str) => str.length;
//function to count words
const word_count = (str) => str.split(" ").length;
//function to count vowel
const vowel_count = (str) => (str.match(/[aeiou]/gi)).length;
//here i am trying to wrap all three functions in one
const sentence_read() = {alphabet_count(), word_count(), vowel_count()};
I am trying to trying to wrap all three functions in one.
const sentence_read = (str) => [alphabet_count(str), word_count(str), vowel_count(str)]
will return an array with your 3 results.
Usage :
let str = "a word";
console.log(sentence_read(str)) // output : [6, 2, 2]
Using a template string
let str = "i am writing an algorithm.";
// function to count alphabets
const alphabet_count = (str) => str.length;
// function to count words
const word_count = (str) => str.split(" ").length;
//function to count vowel
const vowel_count = (str) => (str.match(/[aeiou]/gi)).length;
const sentence_read = (str) => `a_c : ${alphabet_count(str)}, w_c : ${word_count(str)}, v_c : ${vowel_count(str)}`
console.log(sentence_read(str)) // a_c : 26, w_c : 5, v_c : 8
If you want to group the functions in an object, you can use:
const str = "i am writing an algorithm.";
const counter = {
alphabet: (s) => s.length,
word: (s) => s.split(" ").length,
vowel: (s) => (s.match(/[aeiou]/gi)).length
}
const count = (unit, str) => {
if(!counter[unit]) throw Error('Unit does not exist')
return counter[unit](str)
}
console.log(count('alphabet', str)) // 26
console.log(count('word', str)) // 5
console.log(count('vowel', str)) // 8
Related
I have an array with bad words and function, with find it:
let words = textWords.split(' ');
console.log('words', words)
let badWords = listOfBadWords.join('|');
let regex = new RegExp(badWords, 'gi');
let matches = words.reduce((acc, word) => {
if (word.match(regex)) {
let match = word.toLowerCase();
acc[match] = (acc[match] || 0) + 1;
}
return acc;
}, {});
let sortedMatches = Object.entries(matches).sort((a, b) => b[1] - a[1]);
let top5 = sortedMatches.slice(0, 5).map(m => m[0]);
console.log(sortedMatches, top5); // in format [['word', numberOfUsing], ....]
How can i make the output like top 5 words most useable in format: word - numberOfUsing
I personally wouldn't use regular expression here. I'd create an object to count the words with from the badWords array and simply iterate the user's words to increase the counter. Something like that:
const badWords = ['cunt', 'shit', 'idiot', 'motherfucker', 'asshole', 'dickhead', 'slut', 'prick', 'whore', 'wanker'];
const userText = "I met this idiot today, he did behave like an asshole. This idiot treated me like a slut. Can't believe this idiot made me feeling like a cunt. Such an asshole, really. I tried to speak with this asshole, but he was just a dickhead.";
const counterObject = badWords.reduce((acc, curr) => {
acc[curr] = 0;
return acc;
}, {});
userText.split(/[\s,\.]/).forEach(
token => {
if (token in counterObject) counterObject[token]++;
}
);
const topWords = Object.entries(counterObject).sort((a, b) => b[1] - a[1]).slice(0, 5);
console.log(topWords);
I would do it like this
const listOfBadWords = ['is', 'or'];
const badWordsFound = [];
const userString = 'This is a test, works or not, is to be seen';
for(i = 0; i < listOfBadWords.length; i++){
const matches = (userString.match(new RegExp(listOfBadWords[i], 'g')) || []).length;
if(matches)
badWordsFound.push([listOfBadWords[i], matches]);
}
const sorted = badWordsFound.sort((a, b) => b[1] - a[1]);
console.log(sorted);
i have an array ["academy"] and i need count chars from the string in the array.
output:
a:2
c:1
d:1
e:1
m:1
y:1
like this
i tried two for loops
function sumChar(arr){
let alph="abcdefghijklmnopqrstuvxyz";
let count=0;
for (const iterator of arr) {
for(let i=0; i<alph.length; i++){
if(iterator.charAt(i)==alph[i]){
count++;
console.log(`${iterator[i]} : ${count}`);
count=0;
}
}
}
}
console.log(sumChar(["abdulloh"]));
it works wrong
Output:
a : 1
b : 1
h : 1
undefined
Here's a concise method. [...new Set(word.split(''))] creates an array of letters omitting any duplicates. .map takes each letter from that array and runs it through the length checker. ({ [m]: word.split(m).length - 1 }) sets the letter as the object key and the word.split(m).length - 1is a quick way to determine how many times that letter shows up.
const countLetters = word => (
[...new Set(word.split(''))].map(m => ({
[m]: word.split(m).length - 1
})))
console.log(countLetters("academy"))
You can check the occurrences using regex also. in this i made a method which checks for the character in the string. Hope it helps.
word: string = 'abcdefghijklkmnopqrstuvwxyzgg';
charsArrayWithCount = {};
CheckWordCount(): void {
for(var i = 0;i < this.word.length; i++){
if(this.charsArrayWithCount[this.word[i]] === undefined){
this.charsArrayWithCount[this.word[i]] = this.charCount(this.word, this.word[i]);
}
}
console.log(this.charsArrayWithCount);
}
charCount(string, char) {
let expression = new RegExp(char, "g");
return string.match(expression).length;
}
You can simply achieve this requirement with the help of Array.reduce() method.
Live Demo :
const arr = ["academy"];
const res = arr.map(word => {
return word.split('').reduce((obj, cur) => {
obj[cur] = obj[cur] ? obj[cur] + 1 : 1
return obj;
}, {});
});
console.log(res);
I think this is the simplest:
const input = 'academy';
const res = {};
input.split('').forEach(a => res[a] = (res[a] ?? 0) + 1);
console.log(res);
I want to remove special characters and letters from an array and calculate the sum of the remaining integers in the array, in JavaScript.
const arr = ["13,d42", "d44f2", "1g5", "1c42"];
let numbersOnly = (val) => {
if (typeof val === "number") {
// replace number with string to get only string values in an array.
return val;
} else {
let temp = val.split("");
// document.write(temp);
let newArr = [];
for (let i = 0; i < temp.length; i++) {
if (typeof temp[i].parseInt() === 'number') {
document.write(i)
newArr.push(temp[i]);
}
}
// return newArr;
// document.write(newArr)
}
};
let numbers = arr.map(numbersOnly).reduce((partialSum, a) => partialSum + a, 0);
document.write(numbers);
reduce over the array. For each string find the numbers using match with a simple regular expression, then join that array into one string, and then coerce it to a number.
const arr = ['13,d42', 'd44f2', '1g5', '1c42'];
const sum = arr.reduce((sum, str) => {
const num = Number(str.match(/\d/g).join(''));
return sum + num;
}, 0);
console.log(sum);
Sidenote: you probably shouldn't be using document.write:
⚠ Warning: Use of the document.write() method is strongly discouraged.
Can this help you?
const arr = ["13,d42", "d44f2", "1g5", "1c42"];
const onlyNumbers = arr
.map((value) => value.replace(/[^0-9]/g, "")) // get just numbers
.reduce((pv, cv) => parseInt(pv) + parseInt(cv)); // add up the numbers
console.log(onlyNumbers);
I have created getNumber which accepts a string as parameter and return the number which its contain.
For example if we pass "13,d42" so it will gonna return us 1342 as number.
And my another function getTotalSum will call the function for all the string and do some of all numbers which getNumber return;
const arr = ["13,d42", "d44f2", "1g5", "1c42"];
const getNumber = (numberString) => {
let numberRes = '';
for(let i = 0; i< numberString.length;i++){
if(!isNaN(parseFloat(numberString[i]))){
numberRes += numberString[i];
}
}
return parseFloat(numberRes);
}
const getTotalSum = (arr) => {
let sum = 0;
arr.forEach(el =>{
sum += getNumber(el)
});
return sum;}
The solution is quite simple if you only want to parse each individual string in the array.
const arr = ["13,d42", "d44f2", "1g5", "1c42"];
const numbersOnly = (val) => {
const re = /\D/g;
return parseInt(val.replaceAll(re, ""));
}
let numbers = arr.map(numbersOnly).reduce((partialSum, a) => partialSum + a, 0);
console.log(numbers);
But more importantly what answer are you desiring? Are you treating "13,d42" as 13,42 or 1342?
Use Array#map with a regular expression to replace all special characters and letters then use + to convert from string to numeric. Finally, use Array#reduce to add the numbers to get the sum.
const arr = ["13,d42", "d44f2", "1g5", "1c42"],
output = arr
.map(item => +item.replace(/[^\d]+/g,''))
.reduce(
(sum,item) => sum + item,0
);
console.log( output );
Alternatively ...
You can do it without Array#map as follows:
const arr = ["13,d42", "d44f2", "1g5", "1c42"],
output = arr
.reduce(
(sum,item) => sum + +item.replace(/[^\d]+/g,''),0
);
console.log( output );
1941 is correct answere. because "13,d42" is first element of the array. returns 1342
const arr = ["13,d42", "d44f2", "1g5", "1c42"];
console.log(arr.map(a => +a.match(/\d+/g).join('')).reduce((a, b) => a + b, 0)); // 1941 => the sum of [ 1342, 442, 15, 142 ]
// Fn to remove numeric part from input string
const stripNonNumeric=(str)=>{return str.replace(/\D/g,'');}
let input = ["13,d42", "d44f2", "1g5", "1c42"];
// Convert array to numeric array
let numericArray=input.map(item=>(Number(stripNonNumeric(item))))
// Sum array elements
const sum = numericArray.reduce((partialSum, a) => partialSum + a, 0);
console.log(sum);
I am trying to determine groups in a string.
For example "AAABBCCCCD" should have ["AAA", "BB", "CCCC", "D"] as groups based on the pattern in the string.
Here is my simple function to do that:
const patternGroup = (str) => {
let cursor = str[0]
let groups = []
let currentGroup = ""
for (let i = 0; i < str.length; i++) {
let ch = str[i]
if (ch === cursor) {
currentGroup += ch
}
else {
groups.push(currentGroup)
currentGroup = ch
cursor = ch
}
}
if (currentGroup !== "") {
groups.push(currentGroup)
}
return groups
}
It works as intented but I am looking for a simpler function, maybe using map/reduce or regex. Any ideas?
you can simply use RegExp:
var input = "AAABBCCCCD";
const res = input.match(/([^])(\1*)/g);
console.log(res)
Similar to your implementation:
const patternGroupWithReduce = (str) => {
let currentGroup = ""
return str.split("").reduce((acc, cur, i) => {
currentGroup += cur
if (str[i + 1] !== cur) {
acc.push(currentGroup)
currentGroup = ""
}
return acc
}, [])
}
const patternGroupWithRegex = (str) => {
return str.match(/(.)\1*/g)
}
RegEx /(.)\1/g* uses the back reference for the capturing group.
\1* matches the same char as recently captured one as many times as possible.
Here is the visualization for it:
You could use
(.)\1*
As in:
let string = "AAABBCCCCD";
let rx = /(.)\1*/g;
let parts = string.match(rx);
console.log(parts);
See a demo for the expression on regex101.com.
The example below results as expected:
const str = "abbcccddddeeeeeffffff";
const res = str.match(/(.)\1*/g);
console.log(res);
But if I try to group non consecutive letters:
const str = "abxbcxccdxdddexeeeefxfffffxx";
const res = str.match(/(.)\1*/g);
console.log(res);
I would like to get somethig like this:
[ 'a', 'bb', 'xxxxxxx', 'ccc', 'dddd', 'eeeee', 'ffffff']
Sort the string before applying the Regex :
const str = "abxbcxccdxdddexeeeefxfffffxx";
const res = [...str].sort().join('').match(/(.)\1*/g);
console.log(res);
If you absoloutely want them in that order, you can dedup the string and match the letters individually
const str = "abzzzbcxccdxdddexeeeefxfffffxx";
const res = [];
[...new Set(str)].forEach(letter => {
const reg = new RegExp(`${letter}`, "g");
res.push(str.match(reg).join(""));
});
console.log(res);
Here is way to do it without a regex, but you will need an array to hold the results:
var a = []; // (scratch space)
Array.prototype.map.call("abxbcxccdxdddexeeeefxfffffxx", c => c.charCodeAt(0))
.forEach(n => a[n] ? a[n] += String.fromCharCode(n) : a[n] = String.fromCharCode(n));
console.log(a.join(''));
Outputs: "abbcccddddeeeeeffffffxxxxxxx"
And if you need it in order, you can add m to keep a mapping of positions:
var a = [], m = []; // (scratch space; m maps chars to indexes)
Array.prototype.map.call("abxbcxccdxdddexeeeefxfffffxx", c => c.charCodeAt(0))
.forEach(n => (!m[n]&&(m[n]=m.length), a[m[n]] ? a[m[n]] += String.fromCharCode(n) : a[m[n]] = String.fromCharCode(n)));
console.log(a.join(''));
Outputs: "abbxxxxxxxcccddddeeeeeffffff"