Example
฿33.00 => ฿3X.XX
฿111.00 => ฿1XX.XX
฿33,333.00 => ฿3X,XXX.XX
How to replace money "xxx" By Javascript Or jQuery
You could use something like that :
var input="฿33.00";
if (input.length > 2 && input[0] == "฿" && !isNaN(input[1])) {
var output = input.substring(0,2);
for (var i=2; i<input.length; i++) {
output += isNaN(input[i]) ? input[i] : "X";
}
console.log(output);
}
In this code we first check that the transformation is applicable (input has at least 3 characters, first char is the currency symbol, second is a digit), then we create a string that starts with the first two characters of the input and which we continue by iterating over the input, adding an "X" to the output if it's a digit and the character (a dot or comma assumedly) otherwise.
Using a regex, map and replace
const lines = `฿33.00
฿111.00
฿33,333.00`.split(/\s+/)
const res = lines.map(line => {
let [a, b, c] = line.match(/(฿\d)(.*)/); // capture the ฿+first digit plus rest
return b + c.replace(/[0-9]/g, "X"); // replace the numbers in the rest
});
console.log(res)
Related
I need to iterate over an input string and return a string with the count of the frequency of the different vowels in the string. The vowels in the return string should be in the order they appear in the input string. So, if 'hello world' is the function's parameter, the function should return e1o2. The code I have so far is below. It returns e1o2o3. For some reason, it is not stopping the count of o after it hits the o in hello, and seems to be counting the o in world as a separate count. I think it is, finalString += char + sum;, that is causing this. But, I do not know how to create this function in the first place. Thank you for your time.
function vowelFrequency(str) {
let finalString = '';
let sum = 0;
for (let char of str) {
if ('aeiou'.includes(char)) {
sum += 1;
finalString += char + sum;
}
}
return finalString;
};
The main problem is your sum counter. It counts all vowels together.
Better appoach would be to create a dictionary of vowels
where we add +1 every time we met a match.
In short the idea is:
if (char === 'e') {
dic['e'] += 1;
}
const text = 'hello world';
function vowelFrequency(str) {
let finalString = '';
let dic = {};
for (let char of str) {
if ('aeiou'.includes(char)) {
//check if dictionary has no certain vowel
//it happens when we first time meet a vowel
if (!(char in dic)) {
dic[char] = 0;
}
//increment our counter
dic[char]+=1;
}
}
//by the end of the loop
//we have object with { e: 1, o: 2 }
//now we need to gather values into string
//loop through the object
for ([char, count] of Object.entries(dic)) {
finalString += char + count;
}
return finalString;
};
console.log(vowelFrequency(text));
Shorter version of the same solution would be:
function vowelFrequency(str) {
const vowels = 'aeiou';
let dic = [...str].reduce((dic, char) => {
if (vowels.includes(char))
dic[char] = dic[char] + 1 || 1;
return dic;
}, {});
return Object.entries(dic)
.map(([char, count]) => `${char}${count}`)
.join('');
};
One concise approach would be to transform the string via String.prototype.replaceAll (evaluating every character in the string). The following code searches the original string (which you may wish to normalize beforehand with .toLowerCase() for better results) for any character.
"hello world".replaceAll(/./g, ( char, index, str ) =>
!'aeiou'.includes( char ) || str.lastIndexOf( char ) > index
? "" : char + [ ...str ].filter( o => o == char ).length
);
Each character is checked against a list of vowels. We also check to see if the character index is the last index of this character (does it appear multiple times) in the original string. If either of these conditions fail, an empty string is returned in the character's place.
If our character is in our vowel list, and is the last instance of itself, then we split the original string, filter-out non-matching characters, and return the final count of character instances.
The above approach is somewhat of a gimmick. It's concise, but probably not very self-explanatory or maintainable. Realistically, you'd want to take a slightly more verbose approach (see below).
Note that Map is preferred over a standard object to ensure that key-insertion order is preserved.
function charInstanceString ( input, chars = "aeiou" ) {
/**
* Cycle over each character in our string, checking
* if it appears in our `chars` string. If the character
* appears in our `chars` string, we'll update our map
* to reflect the number of instances for the character.
*/
const charMap = new Map();
for ( const char of input ) {
if ( !chars.includes( char ) ) continue;
charMap.set( char, charMap.get( char ) + 1 || 1 );
}
/**
* Cycle over our map, adding each character (and its
* corresponding count) to an output string.
*/
let output = "";
for ( const [ char, count ] of charMap ) {
output += `${ char }${ count }`;
}
return output;
}
I've been practicing simple solutions using what I've been learning / known.
The question I've faced is, how to move the capital letters in the string to the front?
I've solved it, but it's not to my expectation as my original idea was to → find the uppercase letter → put them in an array → concat the uppercase with the original string array with the uppercase letter removed in it.
Hence my question is, how can I remove the capital letter in the first conditional statement so I won't need to create another conditional statement to find the lower case and store the lower case letter in an array?
For example, the input string is 'heLLo' → output would be 'LLheo' (the capital letters are now in front).
Thank you!
function capToFront(s) {
var sp = s.split("");
var caps = [];
var lower = []
for (var i = 0; i < sp.length; i++)
{
if (sp[i] == sp[i].toUpperCase()){
caps.push(sp[i]);
**//How can i remove the capital letter in "sp" array as I've pushed them into the caps Array**
}
if (sp[i] == sp[i].toLowerCase()){
lower.push(sp[i]);
}
}
return caps.join("").concat(lower.join(""));
}
With RegExp, you can accomplish your goal in one line without any loops:
const result = [...'heLLo'].sort(l => /[A-Z]/.test(l) ? -1 : 0).join('');
console.log(result); // LLheo
If you want to ensure the original order among the capital letters is preserved, it will be slightly longer:
const result = [...'Hello World Foo Bar']
.sort((a, b) => /[A-Z]/.test(a) ? /[A-Z]/.test(b) ? 0 : -1 : 0)
.join('');
console.log(result); // HWFBello orld oo ar
You can reach your goal with a smaller loop by using Regex.
function capToFront(sp) {
let upperRgx = /[A-Z]/g;
let upperLetters = sp.match(upperRgx);
for(let i=0; i < upperLetters.length;i++) {
let indx = sp.indexOf(upperLetters[i]);
sp = sp.substring(0,indx)+sp.substring(indx+1,sp.length);
}
sp = upperLetters.join("")+sp;
return sp;
}
console.log(capToFront("heLLo")) // Output: LLheo
Use the Splice method to remove.
function capToFront(s) {
var sp = s.split("");
var caps = [];
var lower = []
for (var i = 0; i < sp.length; i++)
{
if (sp[i] == sp[i].toUpperCase()){
caps.push(sp[i]);
// Use the `splice` method to remove
sp.splice(i, 1);
}
if (sp[i] == sp[i].toLowerCase()){
lower.push(sp[i]);
}
}
console.log('sp', sp);
return caps.join("").concat(lower.join(""));
}
console.log(capToFront("stAck"))
You can also try this approach where you check the ASCII value of characters as the capital letters lie between 65 and 90 then use .sort and .join methods on the array accordingly
function capToFront(s) {
var sp = s.split("");
const res = sp.sort((a,b)=> isCaps(a) ? isCaps(b) ? 0 : -1 : 0)
return res.join("")
}
function isCaps(c){
return c.charCodeAt()>=65 && c.charCodeAt()<=90
}
console.log(capToFront('hIsAmplEStRing'))
I am trying to solve this particular algorithm question:
You are given a license key represented as a string S which consists only alphanumeric character and dashes. The string is separated into N+1 groups by N dashes.
Given a number K, we would want to reformat the strings such that each group contains exactly K characters, except for the first group which could be shorter than K, but still must contain at least one character. Furthermore, there must be a dash inserted between two groups and all lowercase letters should be converted to uppercase.
Given a non-empty string S and a number K, format the string according to the rules described above.
Example 1:
Input: S = "5F3Z-2e-9-w", K = 4
Output: "5F3Z-2E9W"
Explanation: The string S has been split into two parts, each part has 4 characters.
Note that the two extra dashes are not needed and can be removed.
Example 2:
Input: S = "2-5g-3-J", K = 2
Output: "2-5G-3J"
Explanation: The string S has been split into three parts, each part has 2 characters except the first part as it could be shorter as mentioned above.
Note:
The length of string S will not exceed 12,000, and K is a positive integer.
String S consists only of alphanumerical characters (a-z and/or A-Z and/or 0-9) and dashes(-).
String S is non-empty.
I have written the following code:
const licenseKeyFormatting = (S, K) => {
//convert to array, remove special characters, and capitalize
let s = [...S.replace(/\W/g, '').toUpperCase()]
let pos = 1
//from end of array add '-' for every K
for (let i = s.length - 1; i > 0; i--) {
if (pos === K) {
s.splice(i, 0, '-')
pos = 1
i-- //re-index bc adding to the array
}
pos++
}
return s
}
console.log(licenseKeyFormatting("5F3Z-2e-9-w", 4)) //5F3Z-2E9W
console.log(licenseKeyFormatting("2-5g-3-J", 2)) //2-5G-3J
console.log(licenseKeyFormatting("a-a-a-a-", 1)) // this test case fails should be A-A-A-A, I am getting AAA-A
I am pretty sure the flaw in my logic is due to the re-index, but I can't figure out how to address it.
You should not alter the index. Using splice to insert an element pushes the other elements back, however since you iterate from back to front that doesn't matter. You've already handled the shifted elements.
Another issue is setting pos = 1 in the loop. This is directly followed by pos++. So when pos reaches K the value of pos will be reset to 2 at the end of the loop. Either set pos = 0 (in the loop) so it ends on 1 or move pos++ into the else section.
const licenseKeyFormatting = (S, K) => {
//convert to array, remove special characters, and capitalize
let s = [...S.replace(/\W/g, '').toUpperCase()]
let pos = 1
//from end of array add '-' for every K
for (let i = s.length - 1; i > 0; i--) {
if (pos === K) {
s.splice(i, 0, '-')
pos = 0
}
pos++
}
return s.join("") // <- added join for cleaner console output
}
console.log(licenseKeyFormatting("5F3Z-2e-9-w", 4)) //5F3Z-2E9W
console.log(licenseKeyFormatting("2-5g-3-J", 2)) //2-5G-3J
console.log(licenseKeyFormatting("a-a-a-a-", 1)) // this test case fails should be A-A-A-A, I am getting AAA-A
my way....
function licenseKeyFormatting( S, K )
{
let arr = [...S.replace(/\W/g, '').toUpperCase()]
, p = 0
;
for (let i=arr.length;i--;)
{
p = ++p % K // p = (p+1) % K
if (!p&&i) arr.splice(i,0,'-') // if p===0 and i>0
}
return arr.join('')
}
console.log(licenseKeyFormatting("5F3Z-2e-9-w", 4)) // 5F3Z-2E9W
console.log(licenseKeyFormatting("2-5g-3-J", 2)) // 2-5G-3J
console.log(licenseKeyFormatting("a-a-a-a-", 1)) // A-A-A-A
OR: (more simple)
function licenseKeyFormatting( S, K )
{
let arr = [...S.replace(/\W/g, '').toUpperCase()];
for (let p=arr.length-K;p>0;p-=K) arr.splice(p,0,'-');
return arr.join('');
}
console.log( licenseKeyFormatting("5F3Z-2e-9-w", 4)) // 5F3Z-2E9W
console.log( licenseKeyFormatting("2-5g-3-J", 2)) // 2-5G-3J
console.log( licenseKeyFormatting("a-a-a-a-", 1)) // A-A-A-A
I'm trying to do this Codewars problem.
Task
In this simple Kata your task is to create a function that turns a string into a Mexican Wave. You will be passed a string and you must return that string in an array where an uppercase letter is a person standing up.
Rules
The input string will always be lower case but maybe empty.
If the character in the string is whitespace then pass over it as if it was an empty seat.
Example
wave("hello") => ["Hello", "hEllo", "heLlo", "helLo", "hellO"]
My code so far is hosted on this repl.it
My thought process is as follows:
Turn argument into array
manipulate each index of the array at index and then readjust previous index to make a wave pattern
turn array into string
reinsert spaces before logging it to console and restarting the loop
I'm pretty stuck and my mind is stuck on how to use
for(var j = 0; j < indexSpaceNumber.length; j++){
//join and add in the spaces at their former index before returning string
strToArray[indexSpaceNumber[j]].slice(0, " ");
}
to insert the spaces into the string.
If there's any guidance or tips it would be much appreciated. I feel like I'm close, but so frustratingly far.
The main idea would be:
Iterate the characters
Replace the character in the original string with an uppercase version
You can use Array.from() to convert the string to an array, and map each item to a new string. If the character is a space return something falsy (en empty string in the example). After the creating the array, filter all falsy values:
const wave = str =>
Array.from(str, (c,i) => // convert the string to an array
// replace the character with an uppercase version in the original string
c === ' ' ?
''
:
`${str.substring(0, i)}${c.toUpperCase()}${str.substring(i + 1)}`
).filter(c => c)
const result = wave("hello")
console.log(result)
For string with spaces
function wave(str) {
let res = []
str.toLowerCase().split('').forEach((v, i) => {
if(v == ' ') return;
res.push( str.substr(0, i) + v.toUpperCase() + str.substr(i + 1) )
});
return res
}
console.log(wave("hello hello"))
I'd go recursive ;)
You know that for a string of length n you need an array of the same length. That's your exit condition.
You can use the length of the array at each iteration to work out the shape of the next string:
hello [] [Hello] 0: uppercase 1st char and append
hello [Hello] [Hello hEllo] 1: uppercase 2nd char and append
hello [Hello hEllo] [Hello hEllo heLlo] 2: uppercase 3rd char and append
...
const wave =
(str, arr = []) =>
str.length === arr.length
? arr
: wave
( str
, [ ...arr
, str.slice(0, arr.length)
+ str[arr.length].toUpperCase()
+ str.slice(arr.length + 1)
]
);
console.log(wave('hello'));
Go over each char in string and build
Slice str from start till current char + current char to upper case + Slice str from current char to end
const wave = str => {
const res = [];
for (let i = 0; i < str.length; i++) {
res.push(`${str.slice(0, i)}${str[i].toUpperCase()}${str.slice(i + 1)}}`);
}
return res;
};
console.log(wave("hi my name is rylan"));
// Alternate way to do with Array.splice
const wave2 = str => {
const res = [];
for (let i in str) {
const temp = Array.from(str);
temp.splice(i, 1, temp[i].toUpperCase());
res.push(temp)
}
return res.map(x => x.join(''));
};
console.log(wave2("hi my name is rylan"));
I am creating a cipher that takes a string and changes each letter to move forward 3 spaces. For instance "Hello!" would turn into "Khoor!", but I have hit a snag. When people type in something that isn't a letter, like a "!" or a space in between letters, I want to be able to just return that value. So a "!" would stay a "!" and a space would stay a space. I want to create an if statement inside of a loop to accomplish this, but how do I differentiate between letters and non-letters?
Attached is my loop, and I want to be able to put in an if statement so it would read "if input is non-letter, then return input. If input is a letter then move forward 3 spaces."
var 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"];
var string = "Hello World!"
var stringArr = string.split("")
var codedLet = [];
for (var i = 0; i < string.length; i++) {
var input = stringArr[i].toLowerCase()
var codedNum = alphabet.indexOf(input) + 3
codedLet[i] = alphabet[codedNum]
}
There are two ways :
One would be to use regex of the type [a-zA-Z]{1} or you can try something like
if(c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z')
If you need a cipher which shifts symbols, why not to shift all of them?
See the snippet below:
let string = "Hello World!"
const cipher = (s) => [...s].reduce(
(a, l) => a + String.fromCodePoint(l.codePointAt() + 3), '')
const decipher = (s) => [...s].reduce(
(a, l) => a + String.fromCodePoint(l.codePointAt() - 3), '')
let cs = cipher(string)
console.log(cs)
console.log(decipher(cs))