Finding the first non-repeating character javascript [duplicate] - javascript

This question already has answers here:
return the first non repeating character in a string in javascript
(32 answers)
Closed 1 year ago.
I tried to solve the problem below on a site, but they keep saying that something is not right when I reach certain tests.
Given a string s consisting of small English letters, find and return the first instance of a non-repeating character in it. If there is no such character, return "_".
I tried this
function firstNotRepeatingCharacter(s) {
let strArr = s.replace(" ", "").split(""),
newArr = [];
for (let i = 0; i < strArr.length; i++) {
newArr = strArr.filter(lol => lol === strArr[i]);
if (newArr.length === 1) {
return newArr[0];
};
};
return "_";
};
console.log(firstNotRepeatingCharacter("abacabad"));
It works for 16 out of 19 tests. why not all

Thanks all!
I've found an answer.
function firstNotRepeatingCharacter(s) {
let strArr = s.replace(" ", "").split("");
for (let str of strArr)
if(strArr.indexOf(str) == strArr.lastIndexOf(str))
return str;
return "_";
};
console.log(firstNotRepeatingCharacter("abacabad"));

another approach with a better time complexity:
function firstNotRepeatingCharacter(s) {
const seenBefore = new Set();
let result = "_";
for (let i = s.length; i--;) {
const char = s.charAt(i);
if (seenBefore.has(char)) continue;
seenBefore.add(char);
result = char;
}
return result;
}
console.log(firstNotRepeatingCharacter("abacabad"));

Related

Splitting a string, duplicating each character and re-joining to form new string Abcd would become AAbbccdd [duplicate]

This question already has answers here:
Concatenate string through for loop
(4 answers)
Closed 1 year ago.
I need to be able to duplicate the characters of a string and recombine using my function so Abcd would become AAbbccdd etc..
function doubleChar(str) {
let output = str.split("");
let result = "";
for (i = 0; i < str.length; i++) {
result = output[i] + output[i]
}
return (result)
}
console.log(doubleChar("Abcd"));
I know this is is a completely different approach but that is how I (shorthand fanboy) would do it:
const doubleChar = (str) => str.split("").reduce((a, b) => a + b + b, "");
console.log(doubleChar("Abcd"));
If you want to stick to your version. This is how you could make it work:
function doubleChar(str) {
let output = str.split("");
let result = "";
for (i = 0; i < str.length; i++) {
result += output[i] + output[i]; // <- change = to +=
}
return result;
}
console.log(doubleChar("Abcd"));
You're replacing result every time. Change the result = to result += so you append to it instead.
replace
result = output[i] + output[i]
with
result = result + output[i] + output[i]
You can split the string into an array of characters and use flatMap() to duplicate the items, then join back together:
function doubleChar(str) {
return str.split("").flatMap(i => [i,i]).join('')
}
console.log(doubleChar("Abcd"));
Another alternative to do it is to map each character and return it x2:
function doubleChar(str) {
return str.split("").map(c => c+c).join("");
}
console.log(doubleChar("Abcd"));
Good question Jonathan. I would recommend looking into some string functions as well as some array functions.
Here are a few to get started ->
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat
An approach with these functions could be as simple as
function doubleChar(str) { // "abc"
return str.split('') // ["a","b","c"]
.map(char => char.repeat(2)) // ["aa","bb","cc"]
.join(''); // "aabbcc"
}
To simplify your approach, you can iterate over the string character-by-character by using a for of loop
function doubleChar(str) {
let doubledStr = '';
for (let character of str) {
doubledStr += character.repeat(2);
}
return doubledStr;
}

JavaScript remove adjacent duplicate letters [duplicate]

This question already has answers here:
Remove consecutive duplicate characters in a string javascript
(5 answers)
Closed 1 year ago.
I have seen a few examples of this, but they're either not in JS or are terribly inefficient (like the solution I have now). Basically what I want done is a function that takes in a string and removes any characters that are adjacent and the same. As an example, "jjjavvvaaassscript" would become "javascript". What I'm not looking for is where it would become "javscript" (eliminating the second "a"). I do have a working function shown below, but it's absolutely horrendous and I'm looking for a better way to do it.
function removeChar(text, index) {
return(text.slice(0,index)+text.slice(index+1));
}
function removeDuplicates(text) {
var prevChar = "";
var finalT = text;
var i = 0;
for(i = 0; i < text.length; i++) {
if(finalT.charAt(i) == prevChar) {
if(i > finalT.length) {
return finalT;
} else {
finalT = removeChar(finalT, i);
i--;
}
} else {
prevChar = finalT.charAt(i);
}
}
return finalT;
}
Any help would be greatly appreciated!
I'd use a regular expression to match a character, then backreference it as many times as possible (so, for example, it'll match jjj, or a, or vvv, etc), and then replace with the one character:
const removeDuplicates = str => str.replace(/(.)\1*/g, '$1');
console.log(removeDuplicates('jjjavvvaaassscript'));
If you had to iterate more manually, similar to your current method, then:
const removeDuplicates = str => {
let lastChar = str[0];
let finalT = str[0];
for (const char of str.slice(1)) {
if (lastChar !== char) finalT += char;
lastChar = char;
}
return finalT;
};
console.log(removeDuplicates('jjjavvvaaassscript'));

counting the same letters in a string but not in all lenght

I'm starting my adventure with javascript and i got one of first tasks.
I must create function that count letter that most occur in string and write this in console.
For example:
var string = "assssssadaaaAAAasadaaab";
and in console.log should be (7,a) <---
the longest string is 7 consecutive identical characters (yes, before count i use .toLowerCase();, because the task requires it)
So far I have it and I don't know what to do next.
Someone want to help?
var string = "assssssadaaaAAAasadaaab";
var string = string.toLowerCase();
function writeInConsole(){
console.log(string);
var count = (string.match(/a/g) || []).length;
console.log(count);
}
writeInConsole();
One option could be matching all consecutive characters using (.)\1* and sort the result by character length.
Then return an array with the length of the string and the character.
Note that this will take the first longest occurrence in case of multiple characters with the same length.
function writeInConsole(s) {
var m = s.match(/(.)\1*/g);
if (m) {
var res = m.reduce(function(a, b) {
return b.length > a.length ? b : a;
})
return [res.length, res.charAt(0)];
}
return [];
}
["assssssadaaaAAAasadaaab", "a", ""].forEach(s => {
s = s.toLowerCase();
console.log(writeInConsole(s))
});
Another example when you have multiple consecutive characters with the same length
function writeInConsole(s) {
let m = s.match(/(.)\1*/g);
if (m) {
let sorted = m.sort((a, b) => b.length - a.length)
let maxLength = sorted[0].length;
let result = [];
for (let i = 0; i < sorted.length; i++) {
if (sorted[i].length === maxLength) {
result.push([maxLength, sorted[i].charAt(0)]);
continue;
}
break;
}
return result;
}
return [];
}
[
"assssssadaaaAAAasadaaab",
"aaabccc",
"abc",
"yyzzz",
"aa",
""
].forEach(s => {
s = s.toLowerCase();
console.log(writeInConsole(s))
});
I'm no sure if this works for you:
string source = "/once/upon/a/time/";
int count = 0;
foreach (char c in source)
if (c == '/') count++;
The answer given by using regular expressions is more succinct, but since you say you are just starting out with programming, I will offer a verbose one that might be easier to follow.
var string = "assssssadaaaAAAasadaaab";
var string = string.toLowerCase();
function computeLongestRun(s) {
// we set up for the computation at the first character in the string
var longestRunLetter = currentLetter = string[0]
var longestRunLength = currentRunLength = 1
// loop through the string considering one character at a time
for (i = 1; i < s.length; i++) {
if (s[i] == currentLetter) { // is this letter the same as the last one?
currentRunLength++ // if yes, reflect that
} else { // otherwise, check if the current run
// is the longest
if (currentRunLength > longestRunLength) {
longestRunLetter = currentLetter
longestRunLength = currentRunLength
}
// reset to start counting a new run
currentRunLength = 1
currentLetter = s[i]
}
}
return [longestRunLetter, longestRunLength]
}
console.log(computeLongestRun(string))

Trying to make a function that will return longest word in a string [duplicate]

This question already has answers here:
Javascript: find longest word in a string
(33 answers)
Closed 2 years ago.
This what I have so far but it keeps resulting in "undefined" when I run it.
var sentence = 'Hello my friends';
var words = sentence.split;
var longWordLength = 0;
var longword = 'i';
function findLongWord (sentence){
for (a = 0; a < words.length; a++){
if (words[a].length > longWordLength){
longWordLength = words[a].length;
longWord = words [a];
return longWord}
}
console.log(longWord);
String.prototype.split() is a function
You could use a RegExp expression to split by One-or-more spaces / +/
Keep the logic within your function
JS is case sensitive, so take special care
You could use Array.prototype.forEach()
function findLongWord(sentence) {
const words = sentence.split(/ +/);
let longWord = '';
words.forEach(word => {
if (word.length > longWord.length) {
longWord = word;
}
});
return longWord;
}
console.log(findLongWord('Hello my friends')); // "friends"
Example using sort:
const findLongWord = (str) => str.split(/ +/).sort((a, b) => b.length - a.length)[0];
console.log(findLongWord('Hello my friends')); // "friends"

How make a more concise code using the For statement?

I'm new in StackOverflow and JavaScript, I'm trying to get the first letter that repeats from a string considering both uppercase and lowercase letters and counting and obtaining results using the for statement. The problem is that the form I used is too long Analyzing the situation reaches such a point that maybe you can only use a "For" statement for this exercise, which I get to iterate, but not with a cleaner and reduced code has me completely blocked, this is the reason why I request help to understand and continue with the understanding and use of this sentence. In this case, the result was tested in a JavaScript script inside a function and 3 "For" sentences obtaining quite positive results, but I can not create it in 1 only For (Sorry for my bad english google translate)
I making in HTML with JavasScript
var letter = "SYAHSVCXCyXSssssssyBxAVMZsXhZV";
var contendor = [];
var calc = [];
var mycalc = 0;
letter = letter.toUpperCase()
console.log(letter)
function repeats(){
for (var i = 0; i < letter.length; i++) {
if (contendor.includes(letter[i])) {
}else{
contendor.push(letter[i])
calc.push(0)
}
}
for (var p = 0; p < letter.length; p++) {
for (var l = 0; l < contendor.length; l++) {
if (letter[p] == contendor[l]) {
calc [l]= calc [l]+1
}
}
}
for (var f = 0; f < calc.length; f++) {
if ( calc[f] > calc[mycalc]) {
mycalc = f
}
}
}
repeats()
console.log("The most repeated letter its: " + contendor[mycalc]);
I Expected: A result with concise code
It would probably be a lot more concise to use a regular expression: match a character, then lookahead for more characters until you can match that first character again:
var letter = "SYAHSVCXCyXSssssssyBxAVMZsXhZV";
const firstRepeatedRegex = /(.)(?=.*\1)/;
console.log(letter.match(firstRepeatedRegex)[1]);
Of course, if you aren't sure whether a given string contains a repeated character, check that the match isn't null before trying to extract the character:
const input = 'abcde';
const firstRepeatedRegex = /(.)(?=.*\1)/;
const match = input.match(firstRepeatedRegex);
if (match) {
console.log(match[0]);
} else {
console.log('No repeated characters');
}
You could also turn the input into an array and use .find to find the first character whose lastIndexOf is not the same as the index of the character being iterated over:
const getFirstRepeatedCharacter = (str) => {
const chars = [...str];
const char = chars.find((char, i) => chars.lastIndexOf(char) !== i);
return char || 'No repeated characters';
};
console.log(getFirstRepeatedCharacter('abcde'));
console.log(getFirstRepeatedCharacter('SYAHSVCXCyXSssssssyBxAVMZsXhZV'));
If what you're actually looking for is the character that occurs most often, case-insensitive, use reduce to transform the string into an object indexed by character, whose values are the number of occurrences of that character, then identify the largest value:
const getMostRepeatedCharacter = (str) => {
const charsByCount = [...str.toUpperCase()].reduce((a, char) => {
a[char] = (a[char] || 0) + 1;
return a;
}, {});
const mostRepeatedEntry = Object.entries(charsByCount).reduce((a, b) => a[1] >= b[1] ? a : b);
return mostRepeatedEntry[0];
};
console.log(getMostRepeatedCharacter('abcde'));
console.log(getMostRepeatedCharacter('SYAHSVCXCyXSssssssyBxAVMZsXhZV'));
If the first repeated character is what you want, you can push it into an array and check if the character already exists
function getFirstRepeating( str ){
chars = []
for ( var i = 0; i < str.length; i++){
var char = str.charAt(i);
if ( chars.includes( char ) ){
return char;
} else {
chars.push( char );
}
}
return -1;
}
This will return the first repeating character if it exists, or will return -1.
Working
function getFirstRepeating( str ){
chars = []
for ( var i = 0; i < str.length; i++){
var char = str.charAt(i);
if ( chars.includes( char ) ){
return char;
} else {
chars.push( char );
}
}
return -1;
}
console.log(getFirstRepeating("SYAHSVCXCyXSssssssyBxAVMZsXhZV"))
Have you worked with JavaScript objects yet?
You should look into it.
When you loop through your string
let characters = "hemdhdksksbbd";
let charCount = {};
let max = { count: 0, ch: ""}; // will contain max
// rep letter
//Turn string into an array of letters and for
// each letter create a key in the charcount
// object , set it to 1 (meaning that's the first of
// that letter you've found) and any other time
// you see the letter, increment by 1.
characters.split("").forEach(function(character)
{
if(!charCount[character])
charCount[character] = 1;
else
charCount[character]++;
}
//charCount should now contain letters and
// their counts.
//Get the letters from charCount and find the
// max count
Object.keys(charCount). forEach (function(ch){
if(max.count < charCount[ch])
max = { count: charCount[ch], ch: ch};
}
console.log("most reps is: " , max.ch);
This is a pretty terrible solution. It takes 2 loops (reduce) and doesn't handle ties, but it's short and complicated.
Basically keep turning the results into arrays and use array methods split and reduce to find the answer. The first reduce is wrapped in Object.entries() to turn the object back into an array.
let letter = Object.entries(
"SYAHSVCXCyXSssssssyBxAVMZsXhZV".
toUpperCase().
split('').
reduce((p, c) => {
p[c] = isNaN(++p[c]) ? 1 : p[c];
return p;
}, {})
).
reduce((p, c) => p = c[1] > p[1] ? c : p);
console.log(`The most repeated letter is ${letter[0]}, ${letter[1]} times.`);

Categories