I am trying to solve the following issue:
Find the missing letter in the passed letter range and return it. If all letters are present in the range, return undefined.
the inputs that I will get as strings are:
abce (Which should return d)
bcd (which should return undefined)
abcdefghjklmno (which should return i)
yz (which should return undefined)
my code currently looks like this:
function fearNotLetter(str) {
//create alphabet string
//find starting letter in alphabet str, using str
//compare letters sequentially
//if the sequence doesn't match at one point then return letter
//if all letters in str appear then return undefined
var alphabet = ("abcdefgheijklmnopqrstuvwxyz");
var i = 0;
var j = 0;
while (i<alphabet.length && j<str.length) {
i++;
if (alphabet.charCodeAt(i) === str.charCodeAt(j)) {
i++;
j++;
}
else if (alphabet.charCodeAt(i) !== str.charCodeAt(j)) {
i++;
j++;
if (alphabet.charCodeAt(i) === str.charCodeAt(j-1)) {
return alphabet.charCodeAt(i-1);
}
}
}
}
fearNotLetter('abce');
Thanks for your help as always!
I would do it like this:
function fearNotLetter(str) {
var i, j = 0, m = 122;
if (str) {
i = str.charCodeAt(0);
while (i <= m && j < str.length) {
if (String.fromCharCode(i) !== str.charAt(j)) {
return String.fromCharCode(i);
}
i++; j++;
}
}
return undefined;
}
console.log(fearNotLetter('abce')); // "d"
console.log(fearNotLetter('bcd')); // undefined
console.log(fearNotLetter('bcdefh')); // "g"
console.log(fearNotLetter('')); // undefined
console.log(fearNotLetter('abcde')); // undefined
console.log(fearNotLetter('abcdefghjkl')); // "i"
i can go from 97 to 122, this interval corresponds to the ASCII codes of the lower case alphabet.
If you want it not to be case sensitive, just do str = str.toLowerCase() at the beginning of the function.
I think this is the simplest code to do this:
function skippedLetter(str) {
for (var i = 0; i < str.length - 1; i++) {
if (str.charCodeAt(i + 1) - str.charCodeAt(i) != 1) {
return String.fromCharCode(str.charCodeAt(i) + 1);
}
}
}
alert(skippedLetter('abce'));
This version will reject illegal input, accept both upper and lower case, check that there is only 1 hole in the range, and that there is exactly 1 character missing.
function skippedLetter(str) {
if (!str.match(/^[a-zA-Z]+$/)) return;
var letter = "", offset = str.charCodeAt(0);
for (var i = 1; i < str.length; i++) {
var diff = str.charCodeAt(i) - i - offset;
if (diff == 1) letter += String.fromCharCode(i + offset++)
else if (diff) return;
}
if (letter.length == 1) return letter;
}
alert(skippedLetter('123567')); // illegal characters
alert(skippedLetter('')); // empty string
alert(skippedLetter('a')); // too short
alert(skippedLetter('bc')); // nothing missing
alert(skippedLetter('df')); // skipped letter = e
alert(skippedLetter('GHIKLM')); // skipped letter = J
alert(skippedLetter('nOpRsT')); // cases mixed
alert(skippedLetter('nopxyz')); // too many characters missing
alert(skippedLetter('abcefgijk')); // character missing more than once
alert(skippedLetter('abcefgfe')); // out of order
Note that you have a typo in alphabet: There are two "e"s.
You could split the string into an array, then use the some method to short-circuit the loop when you don't find a match:
function fearNotLetter(str) {
var alphabet = 'abcdefghijklmnopqrstuvwxyz',
missing,
i= 0;
str.split('').some(function(l1) {
var l2= alphabet.substr(i++, 1);
if(l1 !== l2) {
if(i===1) missing= undefined;
else missing= l2;
return true;
}
});
return missing;
}
console.log(fearNotLetter('abce')); //d
console.log(fearNotLetter('bcd')); //undefined
console.log(fearNotLetter('abcdefghjklmno')); //i
console.log(fearNotLetter('yz')); //undefined
Another function that may help:
var alphabet = "abcdefgheijklmnopqrstuvwxyz";
function fearNotLetter(a) {
function letterIndex(text, index) {
var letter = text.charAt(0);
if (alphabet.indexOf(letter) !== index) { return alphabet.charAt(index); } else { return letterIndex(text.substring(1), index + 1) }
}
if (alphabet.indexOf(a) === -1) {
return letterIndex(a, alphabet.indexOf(a.charAt(0)));
}
return undefined;
}
fearNotLetter("abc"); //Undefined
fearNotLetter("abce"); //d
fearNotLetter("fgi"); //h
This will do what you're looking for:
Hit run and check your console
function missingLetter (str) {
var alphabet = ("abcdefghijklmnopqrstuvwxyz");
var first = alphabet.indexOf(str[0]);
var strIndex = 0;
var missing;
for (var i = first ; i < str.length ; i++) {
if (str[strIndex] === alphabet[i]) {
strIndex++;
} else {
missing = alphabet[i];
}
}
return missing;
}
console.log(missingLetter("abce"));
console.log(missingLetter("bcd"));
console.log(missingLetter("abcdefghjklmno"));
console.log(missingLetter("yz"));
I think that you wanted to say that if a string doesn't start with "a" than return "undefined". So here's my code:
function fearNotLetter(str) {
var alphabet = ("abcdefgheijklmnopqrstuvwxyz");
var i = 0;
var j = 0;
while (i < alphabet.length && j < str.length) {
if (alphabet.charAt(i) != str.charAt(j)) {
i++;
j++;
if (alphabet.charAt(i - 1) == "a") {
return "undefined";
} else {
return (alphabet.charAt(i - 1));
}
}
i++;
j++;
}
}
alert(fearNotLetter('abce'));
Here's the working JsFiddle.
You wanted the code to return the missing letter so I used CharAt.
You can make an array of letters and then search through it to see if it maches with letters from the string....
function fearNotLetter(str) {
var a = str.split('');
var array = [];
var j = 0;
for (var i = 1; i < a.length; i++) {
var d = a[i].charCodeAt(0);
var c = a[i - 1].charCodeAt(0);
var delta = d - c;
if (delta != 1) {
array[i] = String.fromCharCode(a[i - 1].charCodeAt(0) + 1);
}
}
str = array.join('');
if (str.length === 0) {
return undefined;
} else {
return str;
}
}
fearNotLetter('abcefr');
This is an even shorter answer thanks to RegExp() that allows you to create a Regular Expression on the fly and use match() to strip off the given letters from a generated String that has all the letters in the given range:
function fearNotLetter(str) {
var allChars = '';
var notChars = new RegExp('[^'+str+']','g');
for (var i=0;allChars[allChars.length-1] !== str[str.length-1] ;i++)
allChars += String.fromCharCode(str[0].charCodeAt(0)+i);
return allChars.match(notChars) ? allChars.match(notChars).join('') : undefined;
}
How about this one? it finds all missing letters anywhere between the first and the last given letters:
function fearNotLetter(str) {
var strArr = str.split('');
var missingChars = [], i = 0;
var nextChar = String.fromCharCode(strArr[i].charCodeAt(0)+1);
while (i<strArr.length - 1) {
if (nextChar !== strArr[i+1]){
missingChars.push(nextChar);
nextChar = String.fromCharCode(nextChar.charCodeAt(0)+1);
} else {
i++;
nextChar = String.fromCharCode(strArr[i].charCodeAt(0)+1);
}
}
return missingChars.join('') === '' ? undefined : missingChars.join('') ;
}
console.log(fearNotLetter("ab"));
Here is what I use:
function fearNotLetter(str) {
var firstLtrUnicode = str.charCodeAt(0),
lastLtrUnicode = str.charCodeAt(str.length - 1);
var holder = [];
for (var i=firstLtrUnicode; i<=lastLtrUnicode; i++) {
holder.push(String.fromCharCode(i));
}
var finalStr = holder.join('');
if ( finalStr === str ) { return undefined; }
else { return holder.filter( function(letter) {
return str.split('').indexOf(letter) === -1;
}).join(''); } }
Try this:
function fearNotLetter(str) {
var alp = ('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ').split(''), i;
for (i = alp.indexOf(str.charAt(0)); i < str.length; i++) {
if (str.split('').indexOf(alp[i]) === -1) {
return alp[i];
}
}
return undefined;
}
fearNotLetter('bcd');
Here's my solution, which i find to be quite easy to interpret:
function fearNotLetter(str) {
var missingLetter;
for (var i = 0; i < str.length; i++) {
if (str.charCodeAt(i) - str.charCodeAt(i-1) > 1) {
missingLetter = String.fromCharCode(str.charCodeAt(i) - 1);
}
}
return missingLetter;
}
I just did this challenge. I am a beginner to Javascript so this was my approach, very simple, sometimes you don't have to use the methods they provide but they also help. I hope you can understand it.
function fearNotLetter(str) {
var alphabet= "abcdefghijlmnopqrstuvwxyz";
var piece =alphabet.slice(0, str.length+1);
for(var i=0; i < piece.length; i++ ){
if(str.charCodeAt(0) != 97){
return undefined;
}
else if(str.indexOf(piece[i])===-1){
return piece[i];
}
}// for loop
}
fearNotLetter("abce");// It will return d
fearNotLetter("xy");//It will return undefined
fearNotLetter("bce");//It will return undefined
function fearNotLetter(str) {
//transform the string to an array of characters
str = str.split('');
//generate an array of letters from a to z
var lettersArr = genCharArray('a', 'z');
//transform the array of letters to string
lettersArr = lettersArr.join('');
//substr the a to z string starting from the first letter of the provided
string
lettersArr = lettersArr.substr(lettersArr.indexOf(str[0]), str.length);
//transform it again to an array of letters
lettersArr = lettersArr.split('');
//compare the provided str to the array of letters
for(var i=0; i<lettersArr.length;i++){
if(str[i] !== lettersArr[i])
return lettersArr[i];
}
return undefined;
}
function genCharArray(charA, charZ) {
var a = [], i = charA.charCodeAt(0), j = charZ.charCodeAt(0);
for (; i <= j; ++i) {
a.push(String.fromCharCode(i));
}
return a;
}
fearNotLetter("bcd");
Here's my another answer in missing letters:
function fearNotLetter(str) {
var alphabet = 'abcdefghijklmnopqrstuvwxyz';
var first = alphabet.indexOf(str[0]);
var last = alphabet.indexOf(str[str.length-1]);
var alpha = alphabet.slice(first,last);
for(var i=0;i<str.length;i++){
if(str[i] !== alpha[i]){
return alpha[i];
}
}
}
console.log(fearNotLetter("abce"));
Overview:
const fearNotLetter = str => {
if(str.length < 26) {
return String.fromCharCode(
str.split("")
.map(x=> x.charCodeAt(0))
.sort((a,b) => a-b)
.find((x,i,a) => a[i+1]-x > 1) + 1
);
}
}
1 liner:
const fearNotLetter = str => str.length < 26 ? String.fromCharCode(str.split("").map(x=> x.charCodeAt(0)).sort((a,b) => a-b).find((x,i,a) => a[i+1]-x > 1) + 1) : undefined;
function fearNotLetter(str) {
var allChars = "";
var notChars = new RegExp("[^" + str + "]","g");
for (var i = 0; allChars[allChars.length - 1] !== str[str.length - 1]; i++)
allChars += String.fromCharCode(str[0].charCodeAt(0) + i);
return allChars.match(notChars) ? allChars.match(notChars).join("") : undefined;
}
function fearNotLetter(str) {
let alphabet = "abcdefghijklmnopqrstuvwxyz"
let startingPoint = alphabet.indexOf(str[0]);
let leaterNotMatch = alphabet.slice(startingPoint)
console.log(startingPoint)
for(let i = 0; i<str.length; i +=1){
if(str[i] != leaterNotMatch[i]){
return leaterNotMatch[i];
}
}
}
let result = fearNotLetter("abcdefghjklmno");
console.log(result)
function findMissingLetter(letters) {
const alphabet = ['A', 'B', 'C', 'D', 'E',
'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
let otherAlphabet = [];
if (letters[0] !== letters[0].toUpperCase()) {
otherAlphabet = alphabet.map(item => item.toLowerCase());
} else {
otherAlphabet = alphabet;
}
const firstIndex = otherAlphabet.findIndex((aplhabetEl) => {
return aplhabetEl === letters[0];
});
const lastIndex = otherAlphabet.findIndex((aplhabetEl) => {
return aplhabetEl === letters[letters.length - 1];
});
const sliceAlphabet = otherAlphabet.slice(firstIndex, lastIndex + 1);
let result = '';
for (let i = 0; i < letters.length; i++) {
if (letters[i] !== sliceAlphabet[i]) {
result += sliceAlphabet[I];
}
}
return result.slice(0, 1);
}
You can also solve this question by using a map which we will call seen. For every letter, we will add it to our seen map. Then we will loop through the alphabet checking if we have come across that letter in our seen map.
If we have come across that letter in our seen map, then we will use a boolean flag foundFirstLetter and set that to true. Then inside another conditional foundFirstLetter, we can check if the letter is missing and if it is we can just return the letter because we know it's missing.
This solution works, but it isn't ideal because it uses more space (because of our seen map), unlike the other solutions.
const findMissingLetter = (array) => {
const convertUpperCase = array[0] === array[0].toUpperCase() ? true : false;
const alphabet = "abcdefghijklmnopqrstuvwxyz";
const seen = {};
let foundFirstLetter = false;
// add the words we have run across to our seen map
for(const letter of array){
seen[letter.toLowerCase()] = true;
}
// loop through our alphabet checking if letter is in our map. If we find the first letter, then that means
// if we don't find the next letter in our map then it's missing.
for(const letter of alphabet){
if(seen.hasOwnProperty(letter)){
foundFirstLetter = true;
}
if(foundFirstLetter){
if(!seen.hasOwnProperty(letter)){
if(convertUpperCase){
return letter.toUpperCase();
} else {
return letter;
}
}
}
}
}
function fearNotLetter(str) {
var string = array. join("");
for (var i = 0; i < string. length; i++) {
if (string. charCodeAt(i + 1) - string. charCodeAt(i) != 1) {
return String. fromCharCode(string. charCodeAt(i) + 1);
}
}
return undefined
}
Related
I was wondering if there is a way to check for repeated characters in a string without using double loop. Can this be done with recursion?
An example of the code using double loop (return true or false based on if there are repeated characters in a string):
var charRepeats = function(str) {
for(var i = 0; i <= str.length; i++) {
for(var j = i+1; j <= str.length; j++) {
if(str[j] == str[i]) {
return false;
}
}
}
return true;
}
Many thanks in advance!
This will do:
function hasRepeats (str) {
return /(.).*\1/.test(str);
}
(A recursive solution can be found at the end of this answer)
You could simply use the builtin javascript Array functions some MDN some reference
var text = "test".split("");
text.some(function(v,i,a){
return a.lastIndexOf(v)!=i;
});
callback parameters:
v ... current value of the iteration
i ... current index of the iteration
a ... array being iterated
.split("") create an array from a string
.some(function(v,i,a){ ... }) goes through an array until the function returns true, and ends than right away. (it doesn't loop through the whole array, which is good for performance)
Details to the some function here in the documentation
Here some tests, with several different strings:
var texts = ["test", "rest", "why", "puss"];
for(var idx in texts){
var text = texts[idx].split("");
document.write(text + " -> " + text.some(function(v,i,a){return a.lastIndexOf(v)!=i;}) +"<br/>");
}
//tested on win7 in chrome 46+
If you will want recursion.
Update for recursion:
//recursive function
function checkString(text,index){
if((text.length - index)==0 ){ //stop condition
return false;
}else{
return checkString(text,index + 1)
|| text.substr(0, index).indexOf(text[index])!=-1;
}
}
// example Data to test
var texts = ["test", "rest", "why", "puss"];
for(var idx in texts){
var txt = texts[idx];
document.write( txt + " ->" + checkString(txt,0) + "<br/>");
}
//tested on win7 in chrome 46+
you can use .indexOf() and .lastIndexOf() to determine if an index is repeated. Meaning, if the first occurrence of the character is also the last occurrence, then you know it doesn't repeat. If not true, then it does repeat.
var example = 'hello';
var charRepeats = function(str) {
for (var i=0; i<str.length; i++) {
if ( str.indexOf(str[i]) !== str.lastIndexOf(str[i]) ) {
return false; // repeats
}
}
return true;
}
console.log( charRepeats(example) ); // 'false', because when it hits 'l', the indexOf and lastIndexOf are not the same.
function chkRepeat(word) {
var wordLower = word.toLowerCase();
var wordSet = new Set(wordLower);
var lenWord = wordLower.length;
var lenWordSet =wordSet.size;
if (lenWord === lenWordSet) {
return "false"
} else {
return'true'
}
}
Using regex to solve=>
function isIsogram(str){
return !/(\w).*\1/i.test(str);
}
console.log(isIsogram("isogram"), true );
console.log(isIsogram("aba"), false, "same chars may not be adjacent" );
console.log(isIsogram("moOse"), false, "same chars may not be same case" );
console.log(isIsogram("isIsogram"), false );
console.log(isIsogram(""), true, "an empty string is a valid isogram" );
The algorithm presented has a complexity of (1 + n - (1)) + (1 + n - (2)) + (1 + n - (3)) + ... + (1 + n - (n-1)) = (n-1)*(1 + n) - (n)(n-1)/2 = (n^2 + n - 2)/2 which is O(n2).
So it would be better to use an object to map and remember the characters to check for uniqueness or duplicates. Assuming a maximum data size for each character, this process will be an O(n) algorithm.
function charUnique(s) {
var r = {}, i, x;
for (i=0; i<s.length; i++) {
x = s[i];
if (r[x])
return false;
r[x] = true;
}
return true;
}
On a tiny test case, the function indeed runs a few times faster.
Note that JavaScript strings are defined as sequences of 16-bit unsigned integer values. http://bclary.com/2004/11/07/#a-4.3.16
Hence, we can still implement the same basic algorithm but using a much quicker array lookup rather than an object lookup. The result is approximately 100 times faster now.
var charRepeats = function(str) {
for (var i = 0; i <= str.length; i++) {
for (var j = i + 1; j <= str.length; j++) {
if (str[j] == str[i]) {
return false;
}
}
}
return true;
}
function charUnique(s) {
var r = {},
i, x;
for (i = 0; i < s.length; i++) {
x = s[i];
if (r[x])
return false;
r[x] = true;
}
return true;
}
function charUnique2(s) {
var r = {},
i, x;
for (i = s.length - 1; i > -1; i--) {
x = s[i];
if (r[x])
return false;
r[x] = true;
}
return true;
}
function charCodeUnique(s) {
var r = [],
i, x;
for (i = s.length - 1; i > -1; i--) {
x = s.charCodeAt(i);
if (r[x])
return false;
r[x] = true;
}
return true;
}
function regExpWay(s) {
return /(.).*\1/.test(s);
}
function timer(f) {
var i;
var t0;
var string = [];
for (i = 32; i < 127; i++)
string[string.length] = String.fromCharCode(i);
string = string.join('');
t0 = new Date();
for (i = 0; i < 10000; i++)
f(string);
return (new Date()) - t0;
}
document.write('O(n^2) = ',
timer(charRepeats), ';<br>O(n) = ',
timer(charUnique), ';<br>optimized O(n) = ',
timer(charUnique2), ';<br>more optimized O(n) = ',
timer(charCodeUnique), ';<br>regular expression way = ',
timer(regExpWay));
let myString = "Haammmzzzaaa";
myString = myString
.split("")
.filter((item, index, array) => array.indexOf(item) === index)
.join("");
console.log(myString); // "Hamza"
Another way of doing it using lodash
var _ = require("lodash");
var inputString = "HelLoo world!"
var checkRepeatition = function(inputString) {
let unique = _.uniq(inputString).join('');
if(inputString.length !== unique.length) {
return true; //duplicate characters present!
}
return false;
};
console.log(checkRepeatition(inputString.toLowerCase()));
const str = "afewreociwddwjej";
const repeatedChar=(str)=>{
const result = [];
const strArr = str.toLowerCase().split("").sort().join("").match(/(.)\1+/g);
if (strArr != null) {
strArr.forEach((elem) => {
result.push(elem[0]);
});
}
return result;
}
console.log(...repeatedChar(str));
You can also use the following code to find the repeated character in a string
//Finds character which are repeating in a string
var sample = "success";
function repeatFinder(str) {
let repeat="";
for (let i = 0; i < str.length; i++) {
for (let j = i + 1; j < str.length; j++) {
if (str.charAt(i) == str.charAt(j) && repeat.indexOf(str.charAt(j)) == -1) {
repeat += str.charAt(i);
}
}
}
return repeat;
}
console.log(repeatFinder(sample)); //output: sc
const checkRepeats = (str: string) => {
const arr = str.split('')
const obj: any = {}
for (let i = 0; i < arr.length; i++) {
if (obj[arr[i]]) {
return true
}
obj[arr[i]] = true
}
return false
}
console.log(checkRepeats('abcdea'))
function repeat(str){
let h =new Set()
for(let i=0;i<str.length-1;i++){
let a=str[i]
if(h.has(a)){
console.log(a)
}else{
h.add(a)
}
}
return 0
}
let str = '
function repeat(str){
let h =new Set()
for(let i=0;i<str.length-1;i++){
let a=str[i]
if(h.has(a)){
console.log(a)
}else{
h.add(a)
}
}
return 0
}
let str = 'haiiiiiiiiii'
console.log(repeat(str))
'
console.log(repeat(str))
Cleanest way for me:
Convert the string to an array
Make a set from the array
Compare the length of the set and the array
Example function:
function checkDuplicates(str) {
const strArray = str.split('');
if (strArray.length !== new Set(strArray).size) {
return true;
}
return false;
}
You can use "Set object"!
The Set object lets you store unique values of any type, whether
primitive values or object references. It has some methods to add or to check if a property exist in the object.
Read more about Sets at MDN
Here how i use it:
function isIsogram(str){
let obj = new Set();
for(let i = 0; i < str.length; i++){
if(obj.has(str[i])){
return false
}else{
obj.add(str[i])
}
}
return true
}
isIsogram("Dermatoglyphics") // true
isIsogram("aba")// false
I'm working through some beginner Coderbyte problems and I've come across an interesting dilemma. Here's the problem:
"Using the JavaScript language, have the function LongestWord(sen) take the sen parameter being passed and return the largest word in the string. If there are two or more words that are the same length, return the first word from the
string with that length. Ignore punctuation and assume sen will not be empty."
Here's my code:
function LongestWord(sen) {
var myArray = sen.split(" ");
var lengthOfSubstring = 0;
for (var i = 0; i < myArray.length; i++) {
if (myArray[i].length > lengthOfSubstring) {
lengthOfSubstring = myArray[i].length;
sen = myArray[i];
}
}
return sen;
}
console.log(LongestWord("Argument goes here"));
My code passes every test unless the argument contains punctuation. Is there anyway to remove or ignore it? Every search brings up regex and very intimidating syntax haha
EDIT: used the match() method on the sen parameter courtesy of #Markus
function LongestWord(sen) {
var myArray = sen.match(/[a-z]+/gi);
var lengthOfSubstring = 0;
for (var i = 0; i < myArray.length; i++) {
if (myArray[i].length > lengthOfSubstring) {
lengthOfSubstring = myArray[i].length;
sen = myArray[i];
}
}
return sen;
}
console.log(LongestWord("Argument goes here"));
Without regex:
function LongestWord(sen) {
var wordStart = -1;
var bestWord = null;
var bestLength = 0;
for (var i = 0; i < sen.length; i++) {
var ch = sen[i];
if ('a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z')
{
if (wordStart === -1)
{
wordStart = i;
}
}
else
{
if (wordStart !== -1)
{
var word = sen.substring(wordStart, i);
if (word.length > bestLength)
{
bestLength = word.length;
bestWord = word;
}
wordStart = -1;
}
}
}
if (wordStart !== -1)
{
var word = sen.substring(wordStart);
if (word.length > bestLength)
{
bestLength = word.length;
bestWord = word;
}
wordStart = -1;
}
return bestWord;
}
With regex:
function LongestWord(sen) {
var bestWord = null;
var bestLength = 0;
var matches = sen.match(/[a-z]+/gi);
for (var i = 0; i < matches.length; i++)
var word = matches[i];
if (word.Length > bestLength)
{
bestLength = word.Length;
bestWord = word;
}
}
return bestWord;
}
Without regex
function LongestWord(sen) {
var punct = '\.,-/#!$%^&*;:{}=-_`~()'.split('');
var words = sen.split(" ").map(function(item) {
return item.split('').filter(function(char) {
return punct.indexOf(char) === -1;
}).join('');
});
return words.reduce(function(a, b) {
return a.length > b.length ? a : b;
});
}
With regex
function LongestWord(sen) {
return sen.split(" ").map(function(word) {
return word.replace(/[\.,-\/#!$%\^&\*;:{}=\-_`~()]/gi, '');
}).reduce(function(a, b) {
return a.length > b.length ? a : b;
});
}
Here is one way to do it without regex using a filter function that is pretty compact:
function longestWord(sen) {
// We are using Python's string.punctuation set.
var punct = '!"#$%&\'()*+,-./:;<=>?#[\\]^_`{|}~';
var wordArr = sen.split(' ');
var filteredWordArr = wordArr.map(function (word) {
return word.split('').filter(function (ch) {
return punct.indexOf(ch) < 0;
}).join('');
});
return wordArr[filteredWordArr.reduce(function (maxIdx, currWord, i, fwa) {
return currWord.length > fwa[maxIdx].length ? i : maxIdx;
}, 0)];
}
console.log(longestWord("Çüéâäâ, wouldn't you like to play?")); // wouldn't
This function returns the unfiltered word that has the greatest length after being filtered and compared to other filtered words, which is probably what you want. I noticed that an older version of this code was returning "wouldnt" instead of "wouldn't", but it's fixed now.
Using regex does clean up this code up a bit though. It helps you replace the split, filter, and join operations with a single regex replace operation:
function longestWord(sen) {
var punct = /[!"#$%&'()*+,\-.\/\\:;<=>?#[\]^_`{\|}~]/g;
var wordArr = sen.split(' ');
var filteredWordArr = wordArr.map(function (word) {
return word.replace(punct, '');
});
return wordArr[filteredWordArr.reduce(function (maxIdx, currWord, i, fwa) {
return currWord.length > fwa[maxIdx].length ? i : maxIdx;
}, 0)];
}
Assuming I have the following string "355385". I need a simple JavaScript that can tell me that the most mentioned character is 5. Thank you in advance.
I tried with this one but no results.
var exp = '355385' ;
var exps =exp.split("");
var expCounts = { };
for (var i=0;i<exp.length;i++)
{expCounts["_" + exps[i]] = (expCounts["_" + exps[i]] || 0) + 1 ;
if (expCounts==3) exps=exps[i]; }; exps;
This will loop over every character in the string and keep track of each character's count and the character with the maximum count:
var exp = '3553853335' ;
var expCounts = {};
var maxKey = '';
for(var i = 0; i < exp.length; i++)
{
var key = exp[i];
if(!expCounts[key]){
expCounts[key] = 0;
}
expCounts[key]++;
if(maxKey == '' || expCounts[key] > expCounts[maxKey]){
maxKey = key;
}
}
console.debug(maxKey + ":" + expCounts[maxKey]);
Update:
Here is an ES6 version that will handle strings where multiple character have the same max count
function maxCount(input) {
const {max, ...counts} = (input || "").split("").reduce(
(a, c) => {
a[c] = a[c] ? a[c] + 1 : 1;
a.max = a.max < a[c] ? a[c] : a.max;
return a;
},
{ max: 0 }
);
return Object.entries(counts).filter(([k, v]) => v === max);
}
Example (please excuse the crude output):
maxCount('--aaaa1111--').join(' | ').replace(/,/g, ':');
outputs 1:4 | -:4 | a:4
var getMax = function (str) {
var max = 0,
maxChar = '';
str.split('').forEach(function(char){
if(str.split(char).length > max) {
max = str.split(char).length;
maxChar = char;
}
});
return maxChar;
};
logs
getMax('355385') //5;
getMax('35538533') //3;
in equal case it will return first number
getMax('3553') //3;
var string = "355385",
counter = {};
for (var i = 0, len = string.length; i < len; i += 1) {
counter[string[i]] = (counter[string[i]] || 0) + 1;
}
var biggest = -1, number;
for (var key in counter) {
if (counter[key] > biggest) {
biggest = counter[key];
number = key;
}
}
console.log(number);
# 5
var exp = '355385';
var findMostFrequent = function (string) {
var chars = {}, first = string.charAt(0);
chars[first] = 1;
var maxChar = first, maxCount = 1;
for (var i = 1; i < string.length; i++) {
var char = string.charAt(i);
if (chars[char]) {
chars[char]++;
} else {
chars[char] = 1;
}
if (chars[char] > maxCount) {
maxChar = char;
}
}
return maxChar;
};
Another Solution
function maxChar(str) {
const charMap = {};
let max = 0;
let maxChar = '';
for(let char of str){
if(charMap[char]){
charMap[char]++;
}else{
charMap[char] = 1;
}
}
for(let char in charMap){
if(charMap[char] > max){
max = charMap[char];
maxChar = char;
}
}
return maxChar;
}
Result:
maxChar('355385')
"5"
Another way to get the most frequent character in a string - sort frequency map into an array and then return the first (greatest) value from that array:
function highest (string) {
let array = Array.from(string);
let frequencyMap = {};
array.forEach((value, index) => {
if (!frequencyMap[value]) {
frequencyMap[value] = 0;
}
frequencyMap[value] += 1;
})
let frequencyArray = Object.entries(frequencyMap);
frequencyArray.sort((a, b) => {
if (a[1] < b[1]) {
return 1;
}
if (a[1] > b[1]) {
return -1;
}
return 0;
});
return(frequencyArray[0][0]);
}
console.log(highest("hello World"));
returns "l"
None of the answers above take into consideration that JavaScript internally uses UTF-16
const s = "😄😅😄😄😅😅😄😄😱😱😄";
function getMostFrequentChar(s) {
const len = s.length;
const freq = {};
let maxFreq = 0;
let maxChar;
for (let i = 0; i < len; ++i) {
const isPair = (s.charCodeAt(i) & 0xF800) == 0xD800;
const c = isPair ? s.substr(i++, 2) : s[i];
const f = (freq[c] || 0) + 1;
freq[c] = f;
if (f > maxFreq) {
maxFreq = f;
maxChar = c;
}
}
return {maxFreq, maxChar, freq}
}
console.log(getMostFrequentChar(s));
Note: the code above assumes the string is valid UTF-16. It's possible to construct a string that is not valid UTF-16 in which case maybe you could change isPair to
const isPair = len - i > 1 &&
s.charCodeAt(i ) & 0xF800) == 0xD800 &&
s.charCodeAt(i + 1) & 0xF800) == 0xD800;
But it's not clear what a character with an invalid UTF-16 value means.
It also won't handle more funky unicode
s = "👦🏿👦👦🏿👦👦🏻👦🏽👦🏾👦🏿"
There are many graphmemes that take multiple unicode code points
Also, splitting the string using split is SSSSSSLLLLLOOOOWWWW and a huge memory hog if the string is long.
Here is yet another answer to this question:
For this I have considered that the character can be of whatevert kind except a space
function findHighestFreqInString(str) {
if (!str) return null
let cleanedStr = str.replace(/\s/g, '') //assumes no spaces needed
if (cleanedStr.length === 0) return null
let strObj = {}
let topChar = ''
for (let val of cleanedStr) {
strObj[val] = (strObj[val] || 0) + 1
if (topChar === '' || strObj[val] >= strObj[topChar]) topChar = val
}
return topChar
}
Here is how you would use it:
findHighestFreqInString('my name is Someone') // returns: e
findHighestFreqInString('') // returns: Null
findHighestFreqInString(' ') // returns: Null
Here is:
let str = '355385';
function mostFrequentCharacter(str) {
let charactersArr = str.split(''),
bins = {};
charactersArr.map(el => bins[el] = (bins[el] || 0) + 1);
return Object.keys(bins).map(key => ({
name: key,
count: bins[key]
})).sort((a, b) => b.count - a.count)[0];
}
You can use the following solution to find the most frequent character in a string:
function getMostRepeatedCharacter(string) {
return string.split('').reduce((acc,char)=>{
let len = string.split(char).length - 1;
return len > acc[1] ? [char,len] : acc
},['',0])[0]
}
getMostRepeatedCharacter('wediuaududddd') // d
Want to share this ES6 functional approach. Please provide your input.
function maxChar(myStr) {
let charObj = {};
return [...myStr].reduce((_, char) => {
if (char in charObj) charObj[char]++;
else if (char !== " ") charObj[char] = 1;
return Object.keys(charObj).reduce((a, b) => {
return charObj[a] > charObj[b] ? a : b;
});
});
}
The simplest approach will be like this:
function maxChar(str) {
const charMap = {};
let max = 0;
let maxChar = '';
start by making an object of words and how many they repeated, to do that we have to loop through the string using for of and implementing the conditions:
for (let char of str) {
if (charMap[char]) {
charMap[char]++;
} else {
charMap[char] = 1;
}
}
and now loop through the object using for in
for (let char in charMap) {
if (charMap[char] > max) {
max = charMap[char];
maxChar = char;
}
}
return maxChar;
}
this is another (bizarre) way
It substitute the current character with blank for check how many times is present in the string making the difference of length with original pattern
var str = "355385";
var mostLength = 0;
var characterMostLength;
for(t = 0; t< 10; t++)
{
var res = str.length - str.replace(new RegExp(t, "g"), "").length;
if (res > mostLength){
characterMostLength = t;
mostLength = res;
}
}
function solution(N) {
var textToArr = N.split('');
var newObj = {};
var newArr = [];
textToArr.map((letter) => {
if(letter in newObj){
newObj[letter] = newObj[letter]+1;
} else {
if(letter !== ' '){
newObj = Object.assign(newObj, {[letter]: 1})
}
}
});
for(let i in newObj){
newArr.push({name: i, value: newObj[i]})
}
var res = newArr.sort((a,b) => b.value-a.value)[0];
return res.name+':'+res.value
}
solution("hello world");
this is a simple Idea that only includes one pass-through with a hashmap. The only thing this does not do is handle several max numbers. I really hope you enjoy my solution :) .
function maxChar(str) {
//Create the output and the hashmap
let m = {}, ans
//Loop through the str for each character
//Use reduce array helper because of the accumulator
str.split('').reduce((a, c) => {
//Increments Map at location c(character) unless it does not already exist
m[c] = m[c] + 1|| 1
//This checks to see if the current passthrough of m[c] is greater than or equal to the accumulator, if it is, set the answer equal to the current character. If it's not keep the ans the same.
ans = m[c] >= a ? c : ans
//Only increment the accumulator if Map at location c(character) is greater than the accumulator. Make sure to return it otherwise it won't increment.
return a = m[c] > a ? a + 1 : a
}, 1)
//Lastly return the answer
return ans
}
Simplest way to find maximum number of occurring character in string
var arr = "5255522322";
var freq:any = {};
var num;
for(let i=0;i<arr.length;i++) {
num = arr[i];
freq[num] = freq[num] >= 1 ? freq[num] + 1 : 1;
}
var sortable:any = [];
for(let i in freq)
{
sortable.push(i);
}
var max = freq[sortable[0]];
var data:any = "";
var value = sortable[0];
for(let i=0;i<sortable.length;i++) {
if(max > freq[sortable[i]]){
data = "key" + value + " " + "value" + max;
}else{
value = sortable[i]
max = freq[sortable[i]];
}
}
console.log(data);
function maxChara(string) {
charMap = {};
maxNum = 0;
maxChar = "";
string.toString().split("").forEach(item => {
if (charMap[item]) {
charMap[item]++;
} else {
charMap[item] = 1;
}
});
for (let char in charMap) {
if (charMap[char] > maxNum) {
maxNum = charMap[char];
maxChar = char;
}
}
return maxChar;
}
let result = maxChara(355385);
console.log(result);
Here str will the string that needs to be verified.
function maxCharacter(str){
let str1 = str; let reptCharsCount=0; let ele='';let maxCount=0;
let charArr = str1.split('');
for(let i=0; i< str1.length; i++){
reptCharsCount=0;
for(let j=0; j< str1.length; j++){
if(str1[i] === str1[j]) {
reptCharsCount++;
}
}
if(reptCharsCount > maxCount) {
ele = str1[i];
maxCount = reptCharsCount;
}
}
return ele;
}
input
maxCharacter('asdefdfdsdfseddssdfsdnknmwlqweeeeeeeesssssssssssseeee');
output
"s"
function freq(str) {
var freqObj = {};
str.forEach((item) => {
if (freqObj[item]) {
freqObj[item]++;
}
else {
freqObj[item] = 1;
}
});
return freqObj;
}
function findmaxstr(str) {
let max = 0,res,freqObj;
freqObj = freq(str.split(""));
for(let keys in freqObj){
if (freqObj[keys] > max) {
max = freqObj[keys];
res = keys;
}
}
console.log(res);
return res;
}
findmaxstr("javasdasdsssssscript");
const maxChar = (str) => {
let obj = {};
for (let char of str) {
(!obj[char]) ? obj[char] = 1: obj[char]++;
}
maxCharcount = Math.max(...Object.values(obj));
const key = Object.keys(obj).filter(key => obj[key] === maxCharcount);
console.log(`Most repeated character/characters in the given string "${str}" is/are given below which repeated ${maxCharcount} times`);
console.log(...key);
}
maxChar("355385");
Here is the code, where it also checks for lower and upperCase characters with the same max count and returns a Lower ASCII character as a Max.
function mostFrequent(text) {
let charObj={}
for(let char of text){
if(char!==' '){
if(charObj.hasOwnProperty(char)) charObj[char]=charObj[char]+1;
else charObj[char]= 1
}
}
let maxOccurance= Object.keys(charObj)[0], i=0;
for(let property in charObj){
if(i>0){
if(charObj[property]> charObj[maxOccurance])
maxOccurance= property
else if(charObj[property]=== charObj[maxOccurance])
{
if(property<maxOccurance)
maxOccurance=property
}
}
i++
}
return [maxOccurance, charObj[maxOccurance]]
}
let str = '355385';
let max = 0;
let char = '';
str.split('').forEach((item) => {
let current = str.split(item).length;
if (current > max) {
max = current;
char = item;
}
});
console.log(char + ' occurred ' + (max - 1) + ' times');
var exp = '35585' ;
var expCounts = { };
let maxChar = ''
let count = 0
for(let i = 0; i < exp.length; i++){
let char = exp[i]
expCounts[char] = expCounts[char] + 1 || 1
if(expCounts[char] > count){
maxChar = char
count = expCounts[char]
}
console.log(maxChar)
}
function checkNoofOccurenance(string) {
const arr = [...new Set(string.split(''))].sort();
const finalObj = {};
arr.forEach((item) => {
finalObj[item] = string.split(item).length - 1;
});
const item=Object.keys(finalObj).reduce((occ, toBeComapir)=>finalObj[occ]>finalObj[toBeComapir]?occ:toBeComapir)
return item;
}
Using Hasmaps we can find the most frequent char and occurrence all in O(N) time complexity. Below is the code. I have used one hasmap to save all the values and while i am doing it, i am also calculating the max occurrence and the max char.
var mostFreq = function(s) {
let myMap = new Map();
let temp;
let counter = 0;
let mostFrequentChar;
for(let i =0;i <s.length;i++){
if(myMap.has(s.charAt(i))){
temp = myMap.get(s.charAt(i));
temp = temp + 1;
myMap.delete(s.charAt(i));
myMap.set(s.charAt(i) , temp)
if(temp > counter){
counter = temp;
mostFrequentChar = s.charAt(i);
}
}else{
myMap.set(s.charAt(i), 1)
}
}
//if you want number of occerance of most frequent char = counter
//if you want list of each individual char and its occurrence = myMap
//if you just want the char that is most frequence = mostFrequentChar;
return mostFrequentChar;
};
If you want the count of the letter as well, You can do this
const { letter, count } = input.split("").reduce(
(acc, letter) => {
const count = input.split(letter).length - 1;
return count > acc.count
? { letter, count }
: { letter: acc.letter, count: acc.count };
},
{ letter: "", count: 0 }
);
Here We are splitting the string, applying a reduce to the result. The Reduce Counts how many instances of a character are there in a string, using input.split(letter).length - 1; And if the count is greater than the previous count, updates the accumulated value to be the current value
let string = "355385";
function printFirstRepeat(str){
let output= {};
for (let char of str) {
char = char.toLowerCase();
output[char] = ++output[char] || 1;
if(output[char] > 1) return char;
}
return "Not Found"
}
console.log(printFirstRepeat(string));
Algorithm: Find maximum occurring character in a string (time complex: O(N))
I'll provide my solution to this algo-problem by utilizing the most recent concepts of javascript
const getMaxCharacter = (str) => {
let max = 0;
let maxChar = '';
str.split('').forEach((char) => {
if (str.split(char).length > max) {
max = str.split(char).length - 1;
maxChar = char;
}
});
return `The max letter is : ${maxChar} and the max number of times it is seen is: ${max} times`;
};
Let's express an easy way of testing the function logic I wrote it:
const letter = 'Hello Student';
getMaxCharacter(letter);
In the function developed, I've used the concepts below:
Arrow Function
Anonymous Funciton
Declare property by using let/const
Template Literals
forEach(); (array helper) & split()
This is simple and optimized solution and it returns the first occurring char if there are chars equals in counts
function maxOccurance(str) {
let maxOccurringChar = "";
const charMap = {};
for (let index = 0; index < str.length; index++) {
const ele = str.charAt(index);
if (!charMap[ele]) {
charMap[ele] = {
startIndex: index,
value: 1
};
} else {
charMap[ele].value = charMap[ele].value + 1;
}
if (
!maxOccurringChar ||
charMap[maxOccurringChar].value < charMap[ele].value
) {
maxOccurringChar = ele;
} else if (
charMap[maxOccurringChar].value === charMap[ele].value &&
charMap[ele].startIndex < charMap[maxOccurringChar].startIndex
) {
maxOccurringChar = ele;
}
}
return maxOccurringChar;
}
console.log( maxOccurance("bacdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz")
);
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
</head>
<body>
<p id = "myString">Hello World! I am Julio!</p>
<p id = "mRCharacter"></p>
<script>
var string = document.getElementById("myString").innerHTML;
var mRCharater = mostRepetedCharacter(string);
document.getElementById("mRCharacter").innerHTML = mRCharater;
console.log(mRCharater);
function mostRepetedCharacter(string){
var mRCharater = "";
var strLength = string.length;
var i = 0;
var count = 0;
var max = 0;
var rest = strLength - 1;
while (i < strLength){
var j = i + 1;
while (j <= rest){
if (string[i] === string[j]){
count++;
}
if (count > max){
max = count;
mRCharater = string[i];
}
j++;
}
i++;
count = 0;
}
return mRCharater;
}
</script>
</body>
</html>
enter code here
Have an array set up with a[letter][occurences], but struggling with looping through this array, to check for occurences > 1 and removing the ones that are.
function charFreq(s) {
var i, j;
var a = new Array();
for (j = 0; j < s.length; j++) {
for (i = 0; i < a.length; i++) {
if (a[i][0] == s[j]) {
a[i][1]++;
break;
}
}
if (i == a.length) {
a[i] = [s[j], 1];
}
}
return a[i][0];
}
document.write(charFreq("insert string here"));
This is the mess I've come up with so far:
function check(str) {
var c;
for (c=0; c < a.length; c++) {
if(a[c][1] == 1) {
return true;
break;
} else {
return false;
}
}
}
Using ES6 Set:
// :: unique = Array<any>|string => Array<any>
const unique = xs => [...new Set(xs)]
const dedupe = str => unique(str).join('')
console.log(
unique('foo'), // => ['f', 'o']
dedupe('foo'), // => 'fo'
)
Don't do it that way.
function noDups( s ) {
var chars = {}, rv = '';
for (var i = 0; i < s.length; ++i) {
if (!(s[i] in chars)) {
chars[s[i]] = 1;
rv += s[i];
}
}
return rv;
}
alert(noDups("Shoe fly pie, and apple pan dowdy")); // Shoe flypi,andw
As the length of your string gets longer, your code gets slower by a factor roughly equal to the square of the length of the string.
To delete duplicate characters from an string, you can use the next function that made the user #Cerbrus
function find_unique_characters( string ){
var unique='';
for(var i=0; i<string.length; i++){
if(string.lastIndexOf(string[i]) == string.indexOf(string[i])){
unique += string[i];
}
}
return unique;
}
console.log(find_unique_characters('baraban'));
If you only want to return characters that appear occur once in a
string, check if their last occurrence is at the same position as
their first occurrence.
Your code was returning all characters in the string at least once,
instead of only returning characters that occur no more than once
Link to the thread of stackoverflow Remove duplicate characters from string
Here's a quick way:
str = str.split('').filter(function(v,i,self){
return self.indexOf(v) == i;
}).join('');
function RemoveDuplicateLetters(input) {
var result = '', i = 0, char = '';
while (i < input.length) {
char = input.substring(i, i+1);
result += char;
input = input.replace(char,'');
}
return result;
}
I can't see a splice version, so here's one:
function uniqueChars(s) {
var s = s.split('');
var c, chars = {}, i = 0;
while ((c = s[i])) {
c in chars? s.splice(i, 1) : chars[c] = ++i;
}
return s.join('');
}
This assumes only alpha characters, and upper case not equal to lower case.
function uniqueChars(string){
var i= 0, L= string.length, ustring= '', next;
while(i<L){
next= string.charAt(i++);
if(ustring.indexOf(next)== -1) ustring+= next;
}
return ustring.replace(/[^a-zA-Z]/g, '');
}
var s1= 'The quick red fox jumps over the lazy brown dog.';
uniqueChars(s1)
/* returned value: (String)
Thequickrdfoxjmpsvtlazybwng
*/
This returns any unique character-
function uniqueArray(array){
return array.filter(function(itm, i, T){
return T.indexOf(itm)== i;
});
}
var s1= 'The quick red fox jumps over the lazy brown dog.';
uniqueArray(s1.split('')).join('');
/* returned value: (String)
The quickrdfoxjmpsvtlazybwng.
*/
I want to get position of dots and commas in an array.
w.wer,ads,
should give something like:
[0] > 1
[1] > 5
[2] > 9
How can this be done with javascript?
function getPositions(regex, str) {
var counts = [], m;
while (m = regex.exec(str)) {
counts.push(regex.lastIndex - m[0].length);
}
return counts;
}
// Usage:
getPositions(/[,.]/g, 'w.wer,ads,'); // => [1,5,9]
Try the following
var getAllIndexesOf = function(str, toFind) {
var all = [];
for (var i = 0; i < str.length; i++) {
if (toFind.indexOf(str[i]) >= 0) {
all.push(i);
}
}
return all;
}
var result = getAllIndexsOf("w.wer,ads,", [".", ","]);
Option 1
Simply loop through each character in the string:
var myString = "w.wer,ads,";
var matchedIndexes = [];
for (var i = 0; i < myString.length; i++) {
if (myString[i] == "," || myString[i] == ".") {
matchedIndexes.push(i);
}
}
Here's a working fiddle.
Option 2
If you wanted to get a bit fancier with it, you could create an object that stores the position and the character at that position:
var myString = "w.wer,ads,";
var matchedIndexes = [];
for (var i = 0; i < myString.length; i++) {
if (myString[i] == "," || myString[i] == ".") {
matchedIndexes.push(new myMatch(myString[i], i));
}
}
function myMatch(position, character) {
this.position = position;
this.character = character;
}
Result:
Here's a working fiddle.
function dotsAndCommas(s) {
var rv = [];
for (var i = 0; i < s.length; ++i) {
if (s[i] === '.' || s[i] === ',') rv.push(i);
}
return rv;
}
Basically, just do it. There's no shortcut way I can think of to do it with a regex.
Probably not ideal, but as a thought experiment, here is a way to do it with built-in javascript functions (no explicit loops):
var pos = mystr.split(/[,.]/).slice(0,-1).map(function(val, i, a) { return a.slice(0, i+1).join('').length+i; });
Demo: http://jsfiddle.net/jtbowden/hHSB2/
To get rid of the nested .slice() which is O(n^2):
var pos = mystr.split(/[,.]/).slice(0,-1).map(function(val, i, a) { return a[i] = val.length+(a[i-1]||-1)+1; });
Demo: http://jsfiddle.net/jtbowden/hHSB2/1/
And, yes, it is still ugly and pointless.
Yet another almost one-liner:
var q = [];
[].forEach.call('w.wer,ads,', function(v, i) { /[,.]/.test(v) ? q.push(i) : 0 } );
// q == [1,5,9]
I would loop through the string and check each character like so:
var s = "w.wer,ads,";
var arr = new Array();
for( var i = 0; i < s.length; i++ ) {
if( s.charAt(i) == "." || s.charAt(i) == "," )
arr.push(i);
}
for( var i = 0; i < arr.length; i++ ) {
document.write( arr[i] );
}
Since there're 5 solutions already, I'll write my almost one-liner.
function dotsAndCommasPositions(str) {
var i = -1;
return str.split(/[.,]/).slice(0, -1).map(function(s){ return i += s.length + 1; });
};
You can create a function that loops through all the characters and saves the index of . and ,.
function getPositionsOfDotsCommas(str) {
var result = [];
for (var i = 0; i < str.length; i++) {
if (str[i] === '.' || str[i] === ',') {
result.push(i);
}
}
return result;
}