Why doesn't modify each char of a string? - javascript

I don't understand why the for loop doesn't modify the chars of a string.
this is
function testing (str) {
let other_str = str
for (let i = 0; i < other_str.length; i++) {
other_str[i] = 'g'
}
return other_str;
}
console.log(testing('hey'));
I am aware that i can use other ways but i want to understand this.

Strings are immutable , convert the string to an array, do the modifications and join it back :
function testing(str) {
let other_str = [...str];
for (let i = 0; i < other_str.length; i++) {
other_str[i] = 'g';
}
return other_str.join('');
}
console.log(testing('hey'));

Related

JavaScript How to Create a Function that returns a string with number of times a characters shows up in a string

I am trying to figure out how to make a function that takes a string. Then it needs to return a string with each letter that appears in the function along with the number of times it appears in the string. For instance "eggs" should return e1g2s1.
function charRepString(word) {
var array = [];
var strCount = '';
var countArr = [];
// Need an Array with all the characters that appear in the String
for (var i = 0; i < word.length; i++) {
if (array.indexOf(word[i]) === false) {
array.push(word[i]);
}
}
// Need to iterate through the word and compare it with each char in the Array with characters and save the count of each char.
for (var j = 0; j < word.length; i++) {
for (var k = 0; k < array.length; k++){
var count = 0;
if (word[i] === array[k]){
count++;
}
countArr.push(count);
}
// Then I need to put the arrays into a string with each character before the number of times its repeated.
return strCount;
}
console.log(charRepString("taco")); //t1a1co1
console.log(charRepString("egg")); //e1g2
let str = prompt('type a string ') || 'taco'
function getcount(str) {
str = str.split('')
let obj = {}
for (i in str) {
let char = str[i]
let keys = Object.getOwnPropertyNames(obj)
if (keys.includes(char)) {
obj[char] += 1
} else {
obj[char] = 1
}
}
let result = ''
Object.getOwnPropertyNames(obj).forEach((prop) => {
result += prop + obj[prop]
})
return result
}
console.log(getcount(str))
If the order of the alphanumeric symbols matters
const str = "10zza";
const counted = [...[...str].reduce((m, s) => (
m.set(s, (m.get(s) || 0) + 1), m
), new Map())].flat().join("");
console.log(counted); // "1101z2a1"
Or also like (as suggested by Bravo):
const str = "10zza";
const counted = [...new Set([...str])].map((s) =>
`${s}${str.split(s).length-1}`
).join("");
console.log(counted); // "1101z2a1"
A more clear and verbose solution-
Let m be max number of symbols in charset
Time complexity- O(n log(m))
Space complexity- O(m)
function countFrequencies(str) {
const freqs = new Map()
for (const char of str) {
const prevFreq = freqs.get(char) || 0
freqs.set(char, prevFreq + 1)
}
return freqs
}
function getCountStr(str) {
const freqs = countFrequencies(str)
const isListed = new Set()
const resultArray = []
for (const char of str) {
if (isListed.has(char)) continue
resultArray.push(char)
resultArray.push(freqs.get(char))
isListed.add(char)
}
return resultArray.join("")
}
console.log(getCountStr("egg"))
console.log(getCountStr("taco"))
console.log(getCountStr("10za"))
Using Set constructor, first we will get the unique data.
function myfun(str){
let createSet = new Set(str);
let newArr = [...createSet].map(function(elem){
return `${elem}${str.split(elem).length-1}`
});
let newStr = newArr.join('');
console.log(newStr);
}
myfun('array');

Common Character Count in Strings JavaScript

Here is the problem:
Given two strings, find the number of common characters between them.
For s1 = "aabcc" and s2 = "adcaa", the output should be 3.
I have written this code :
function commonCharacterCount(s1, s2) {
var count = 0;
var str = "";
for (var i = 0; i < s1.length; i++) {
if (s2.indexOf(s1[i]) > -1 && str.indexOf(s1[i]) == -1) {
count++;
str.concat(s1[i])
}
}
return count;
}
console.log(commonCharacterCount("aabcc", "adcaa"));
It doesn't give the right answer, I wanna know where I am wrong?
There are other more efficient answers, but this answer is easier to understand. This loops through the first string, and checks if the second string contains that value. If it does, count increases and that element from s2 is removed to prevent duplicates.
function commonCharacterCount(s1, s2) {
var count = 0;
s1 = Array.from(s1);
s2 = Array.from(s2);
s1.forEach(e => {
if (s2.includes(e)) {
count++;
s2.splice(s2.indexOf(e), 1);
}
});
return count;
}
console.log(commonCharacterCount("aabcc", "adcaa"));
You can do that in following steps:
Create a function that return an object. With keys as letters and count as values
Get that count object of your both strings in the main function
Iterate through any of the object using for..in
Check other object have the key of first object.
If it have add the least one to count using Math.min()
let s1 = "aabcc"
let s2 = "adcaa"
function countChars(arr){
let obj = {};
arr.forEach(i => obj[i] ? obj[i]++ : obj[i] = 1);
return obj;
}
function common([...s1],[...s2]){
s1 = countChars(s1);
s2 = countChars(s2);
let count = 0;
for(let key in s1){
if(s2[key]) count += Math.min(s1[key],s2[key]);
}
return count
}
console.log(common(s1,s2))
After posting the question, i found that i havent looked the example well. i thought it wants unique common characters ..
and i changed it and now its right
function commonCharacterCount(s1, s2) {
var count = 0;
var str="";
for(var i=0; i<s1.length ; i++){
if(s2.indexOf(s1[i])>-1){
count++;
s2=s2.replace(s1[i],'');
}
}
return count;
}
Create 2 objects containing characters and their count for strings s1
and s2
Count the common keys in 2 objects and return count - Sum the common keys with minimum count in two strings
O(n) - time and O(n) - space complexities
function commonCharacterCount(s1, s2) {
let obj1 = {}
let obj2 = {}
for(let char of s1){
if(!obj1[char]) {
obj1[char] = 1
} else
obj1[char]++
}
for(let char of s2){
if(!obj2[char]) {
obj2[char] = 1
} else
obj2[char]++
}
console.log(obj1,obj2)
let count = 0
for(let key in obj1 ){
if(obj2[key])
count += Math.min(obj1[key],obj2[key])
}
return count
}
I think it would be a easier way to understand. :)
function commonCharacterCount(s1: string, s2: string): number {
let vs1 = [];
let vs2 = [];
let counter = 0;
vs1 = Array.from(s1);
vs2 = Array.from(s2);
vs1.sort();
vs2.sort();
let match_char = [];
for(let i = 0; i < vs1.length; i++){
for(let j = 0; j < vs2.length; j++){
if(vs1[i] == vs2[j]){
match_char.push(vs1[i]);
vs2.splice(j, 1);
break;
}
}
}
return match_char.length;
}
JavaScript ES6 clean solution. Use for...of loop and includes method.
var commonCharacterCount = (s1, s2) => {
const result = [];
const reference = [...s1];
let str = s2;
for (const letter of reference) {
if (str.includes(letter)) {
result.push(letter);
str = str.replace(letter, '');
}
}
// ['a', 'a', 'c'];
return result.length;
};
// Test:
console.log(commonCharacterCount('aabcc', 'adcaa'));
console.log(commonCharacterCount('abcd', 'aad'));
console.log(commonCharacterCount('geeksforgeeks', 'platformforgeeks'));
Cause .concat does not mutate the string called on, but it returns a new one, do:
str = str.concat(s1[i]);
or just
str += s1[i];
You can store the frequencies of each of the characters and go over this map (char->frequency) and find the common ones.
function common(a, b) {
const m1 = {};
const m2 = {};
let count = 0;
for (const c of a) m1[c] = m1[c] ? m1[c]+1 : 1;
for (const c of b) m2[c] = m2[c] ? m2[c]+1 : 1;
for (const c of Object.keys(m1)) if (m2[c]) count += Math.min(m1[c], m2[c]);
return count;
}

Ho to reverse split string into a JavaScript array?

I want to use one loop to split or explode a string into an array like
"Work" // -> var strArray = [k, rk, ork, work]
I tried for loop, but I know this is not an efficient.
for (let index = 0; index < word.length; index++)
{
strArray.push(word[word.length - 1]);
}
Any idea?
It looks like you may want to be sliceing your string. Here's something that'll do that:
function wordSplit(word) {
let strArray = [];
for (let i = 0; i < word.length; i++) {
strArray.push(word.slice(i));
}
return strArray;
}
And a fiddle: https://jsfiddle.net/13kephm9/7/
You can split the string, and iterate the array with Array#map, and generate the string using slice:
var word = 'work';
var result = word.split('').map(function(l, i) {
return word.slice(-i - 1);
});
console.log(result);
for (let index = 0; index < word.length; index++)
{
strArray.push(word.slice(index));
}
array string elements reversing
function rev(arr){
var text = new Array;
for(var i= arr.length-1;i>= 0;i--){
text.push(arr[i]);
}
return text.join();
}
console.log(rev(["a","b","c"]));
`print`

replace all vowels in a string javascript

I am trying to write a function that will remove all vowels in a given string in JS. I understand that I can just write string.replace(/[aeiou]/gi,"") but I am trying to complete it a different way...this is what I have so far... thank you!
I first made a different function called IsaVowel that will return the character if it is a vowel...
function withoutVowels(string) {
var withoutVowels = "";
for (var i = 0; i < string.length; i++) {
if (isaVowel(string[i])) {
***not sure what to put here to remove vowels***
}
}
return withoutVowels;
}
Use accumulator pattern.
function withoutVowels(string) {
var withoutVowels = "";
for (var i = 0; i < string.length; i++) {
if (!isVowel(string[i])) {
withoutVowels += string[i];
}
}
return withoutVowels;
}
function isVowel(char) {
return 'aeiou'.includes(char);
}
console.log(withoutVowels('Hello World!'));
I tried doing this problem by first splitting the string into an array, while also creating an array of vowels. Then go through each element in the string array and check whether it's in my vowel array. If it is not in my vowel array, push it to the withoutVowels array. At the end of the for loop, join all elements in the withoutvowels array and return.
function withoutVowels(string) {
var strWithoutVowels = [];
string = string.split('');
var vowels = ['a', 'e', 'i', 'o', 'u'];
for (var i = 0; i < string.length; i++) {
if (vowels.indexOf(string[i]) < 0) {
strWithoutVowels.push(string[i])
}
}
strWithoutVowels = strWithoutVowels.join('');
return strWithoutVowels;
}
console.log(withoutVowels('Hello World!'))
I think the easiest way is to use a regex; it's cleaner and faster compared to all your loops. Below is the code.
string.replace(/[aeiou]/gi, '');
the gi in the code means no matter the case whether uppercase or lowercase so long as its a vowel, it will be removed

javascript loop iterating too much

Trying a fun problem of replacing vowels in a string with the next vowel in line aka a->e, e->i, i->o, o->u, not accounting for "u". Starting with an array instead of a string. My second loop (to iterate over vowel array elements) is ignoring my "j
var vowelChange = function(vowelArray, stringToChange) {
for (var i = 0; i<stringToChange.length; i++) {
for (var j = 0; j<vowelArray.length; j++) {
if (stringToChange[i]===vowelArray[j]) {
var newCharacter = vowelArray[j+1]
stringToChange[i] = newCharacter
i++
}
}
}
return stringToChange
};
I'm using node-debug to set breakpoints in a browser, and j is looping to 5 before starting over at 0. I get the correct output, but j should stop at 4...
EDIT
Can somebody explain how I'm using join incorrectly, because I can't get my function to output a string instead of just an array.
var vowelChange = function(vowelArray, stringToChange) {
for (var i = 0; i<stringToChange.length; i++) {
for (var j = 0; j<vowelArray.length-1; j++) {
if (stringToChange[i]===vowelArray[j]) {
stringToChange[i] = vowelArray[j+1]
break
}
}
}
stringToChange = stringToChange.join('')
return stringToChange
};
var vowels = ['a','e','i','o','u']
var firstName = ['t', 'e', 's', 't']
vowelChange(vowels, firstName)
console.log(firstName)
Assuming vowelArray is 0-indexed...
var vowelChange = function(vowelArray, stringToChange) {
for (var i = 0; i<stringToChange.length; i++) {
for (var j = 0; j<vowelArray.length - 1; j++) {
if (stringToChange[i]===vowelArray[j]) {
stringToChange[i] = vowelArray[j+1];
break;
}
}
}
return stringToChange
};
In JavaScript, strings are immutable objects, which means that the
characters within them may not be changed and that any operations on
strings actually create new strings.
So,if you try to change any index of the string, the original string won't change
node
> str = "hello this is dummy string";
'hello this is dummy string'
> str[0] = "w";
'w'
> str
'hello this is dummy string'
So, stringToChange[i] = vowelArray[j+1]; won't work
Could split the string and then join
var vowelChange = function(vowelArray, stringToChange) {
stringToChange = stringToChange.split('');
for(var i=0; i<stringToChange.length;i++){
for(var j=0;j<vowelArray.length-1;j++){
if(stringToChange[i] == vowelArray[j]){
stringToChange[i] = vowelArray[j+1];
break;
}
}
}
stringToChange = stringToChange.join('');
return stringToChange;
};
Example

Categories