How to make abbreviations/acronyms in JavaScript? - javascript

new to coding I'm trying to make a function that makes "abbreviations/acronyms" of words, e.g. 'I love you' -> 'ily'.
I've tried rewriting the code in many ways but console.log only shows me the first letter of the first given word.
function makeAbbr(words) {
let abbrev = words[0];
let after = 0;
let i = 0;
for (const letter of words) {
if (letter === '') {
i = words.indexOf('', after);
abbrev += words[i + 1];
}
after++;
}
return abbrev;
}
const words = 'a bc def';
let result = makeAbbr(words);
console.log(result)

Without using arrays. But you really should learn about them.
Start by trimming leading and trailing whitespace.
Add the first character to your acronym.
Loop over the rest of the string and add the current character to the acronym if the previous character was a space (and the current character isn't).
function makeAbbr(words) {
words = words.trim();
const length = words.length;
let acronym = words[0];
for(let i = 1; i < length; i++) {
if(words[i - 1] === ' ' && words[i] !== ' ') {
acronym += words[i];
}
}
return acronym;
}
console.log(makeAbbr('I love you'));
console.log(makeAbbr('I love you'));
console.log(makeAbbr(' I love you '));
And here's the version for GottZ
function w(char) {
char = char.toLocaleLowerCase();
const coll = Intl.Collator('en');
const cmpA = coll.compare(char, 'a');
const cmpZ = coll.compare(char, 'z');
return cmpA >= 0 && cmpZ <= 0;
}
function makeAbbr(words) {
words = words.trim();
const length = words.length;
if(!length) return '';
let acronym = words[0];
for(let i = 1; i < length; i++) {
if(!w(words[i - 1]) && w(words[i])) {
acronym += words[i];
}
}
return acronym;
}
console.log(makeAbbr('I love you'));
console.log(makeAbbr('I love you'));
console.log(makeAbbr(' I love you '));
console.log(makeAbbr(' \tI ... ! love \n\r .you '));
console.log(makeAbbr(' \tI ... ! Löve \n\r .ÿou '));

Since you wanted something using your approach, try this (code is commented)
function makeAbbr(words) {
let abbrev = "";
for (let i = 0; i < words.length - 1; i++) { // Loop through every character except the last one
if (i == 0 && words[i] != " ") { // Add the first character
abbrev += words[i];
} else if (words[i] == " " && words[i + 1] != " ") { // If current character is space and next character isn't
abbrev += words[i + 1];
}
}
return abbrev.toLowerCase();
}
const words = 'a bc def';
let result = makeAbbr(words);
console.log(result)

here is my implementation of your function:
Split the sentence into an array, get the first letter of each word and join them into one string.
const makeAbbr = string => string.split(' ').map(word => word[0]).join('');
console.log(makeAbbr('stack overflow'));
console.log(makeAbbr('i love you'));
`

If you want to use your approach exactly, you had a typo on the line specified. A character can never be "" (an empty string), but a character can be a space " ". Fixing this typo makes your solution work.
function makeAbbr(words) {
let abbrev = words[0];
let after = 0;
let i = 0;
for (const letter of words) {
if (letter === ' ') { // This line here
i = words.indexOf(' ', after);
abbrev += words[i + 1];
}
after++;
}
return abbrev.toLowerCase(); // Also added .toLowerCase()
}
const words = 'a bc def';
let result = makeAbbr(words);
console.log(result)

There are couple of things tripping you up.
let abbrev = words[0]; is just taking the first letter of the word string you passed into the function, and at some point adding something new to it.
for (const letter of words) {...}: for/of statements are used for iterating over arrays, not strings.
Here's a remixed version of your code. It still uses for/of but this time we're creating an array of words from the string and iterating over that instead.
function makeAbbr(str) {
// Initialise `abbrev`
let abbrev = '';
// `split` the string into an array of words
// using a space as the delimiter
const words = str.split(' ');
// Now we can use `for/of` to iterate
// over the array of words
for (const word of words) {
// Now concatenate the lowercase first
// letter of each word to `abbrev`
abbrev += word[0].toLowerCase();
}
return abbrev;
}
console.log(makeAbbr('I love you'));
console.log(makeAbbr('One Two Three Four Five'));

Related

Specific Array element replace

I'm solving a simple problem where I need to capitalize the first alphabet of all words. I was able to do that but I have another string vn52tqsd0e4a if any of my output is matched with this string I have to replace it with --[matched string]-- .
so the expected output should be H--e--llo Worl--d--
but when I'm trying to replace the element with -- it's not doing anything. I tried replace() method as well but it didn't work. I don't know what I'm doing wrong here.
function LetterCapitalize(str) {
// code goes here
let array = str.split(" ")
for (let i=0; i<array.length; i++){
array[i] = array[i].charAt(0).toUpperCase() + array[i].slice(1)
}
let output = array.join(" ") ;
let comp = "vn52tqsd0e4a".split("");
for (let i=0; i<output.length; i++){
comp.map(el=> {
if(output[i] === el){
console.log( `matched ${output[i]}` )
output[i] = `--${output[i]}--`;
console.log(output[i]);
}
})
//
}
console.log(output);
}
LetterCapitalize("hello world");
You can achieve this using split, map, join as:
function LetterCapitalize(str) {
// code goes here
let array = str.split(' ');
for (let i = 0; i < array.length; i++) {
array[i] = array[i].charAt(0).toUpperCase() + array[i].slice(1);
}
let output = array.join(' ');
let comp = 'vn52tqsd0e4a'.split('');
const result = output
.split('')
.map((c) => (comp.includes(c) ? `--${c}--` : c))
.join('');
console.log(result);
}
LetterCapitalize('hello world');
You coulduse Array.reduce() to iterate over the str argument and either capitalize or replace depending on the character.
If the preceeding value is a space we'll capitalize, otherwise if the character is in the comp value, we'll replace with --${char}--.
function LetterCapitalize(str) {
const comp = "vn52tqsd0e4a";
return [...str].reduce((acc, char, idx, a) => {
if (idx === 0 || a[idx - 1] === ' ') {
char = char.toUpperCase();
} else if (comp.includes(char)) {
char = `--${char}--`;
}
return acc + char;
}, '')
}
console.log(LetterCapitalize("hello world"));
console.log(LetterCapitalize("hey man"));
What you say to JavaScript in the piece of code is that it should fit 5 characters in a place that can only hold one character.
output[i] = `--${output[i]}--`;
You need to change it to something like this (code below may not work):
output = output.substring(0,i-1) + el + output.substring(i+1,output.length - i-1);
I recommend using the string.replaceAll function instead. If you create a loop yourself you'll get problems when adding more characters on a place where original one character was present.
function LetterCapitalize(str) {
// code goes here
let array = str.split(" ")
for (let i=0; i<array.length; i++){
array[i] = array[i].charAt(0).toUpperCase() + array[i].slice(1)
}
let output = array.join(" ") ;
let comp = "vn52tqsd0e4a".split("");
comp.map(el=> {
output = output.replaceAll(el, '--' + el + '--');
});
console.log(output);
}
LetterCapitalize("hello world");

JS: given a string, change all the symbols between the first and the last letters of each word of the string if the word starts and ends with 'a'

Example:
aza asssa axxxa rrra -> a!a a!!!a a!!!a rrra
So far I've come up with this solution:
const argument = "aza asssa axxxa rrra";
const amount_of_spaces = [...argument].filter(x => x === " ").length;
let j = 0;
const argument__clone = [...argument];
const space__indices = [];
function do__stuff() {
while (j < amount_of_spaces) {
space__indices.push(argument__clone.indexOf(" ") + j);
argument__clone.splice((argument__clone.indexOf(" ")), 1);
j++;
do__stuff();
}
};
do__stuff();
const words = [];
let word = '';
for (let i = 0; i < argument.length; i++) {
if (!(space__indices.includes(i))) {
word += argument[i];
}
else {
words.push(word);
word = '';
}
}
words.push(word);
let new__word = '';
const new__words = [];
const words__static = [];
for (i of words) {
if (i[0] === 'a' && i[i.length - 1] === 'a') {
for (let j = 1; j < i.length - 1; j++) {
new__word += "!";
}
new__words.push(new__word);
new__word = '';
}
else {
words__static.push(i);
}
}
new__words.map(i => "a" + i + "a");
console.log(new__words);
console.log(words__static);
So one array stores the indices of spaces and the other one stores the words from the given string. We can separate the words because we know when one ends because we have the array with space indices. Then we check for each word whether it starts with 'a' and ends with 'a'. If the requirements are met we change all the letters within the word for "!" (excluding the very first and the very last ones). If the requirements are not met we store the word into the other array.
Eventually we have two arrays that I want to concatenate into one. The problems is if I was given something like this:
aza asssa rrra axxxa
It wouldn't have worked because of the order
Is there any better solution?
A regular expression would be simpler. Match an a after a word boundary, match more non-space characters, and finally match another a followed by a word boundary.
const input = 'aza asssa axxxa rrra';
const output = input.replace(
/(?<=\ba)\S+(?=a\b)/g,
interiorWord => '!'.repeat(interiorWord.length)
);
console.log(output);
For a more manual approach, split the input by spaces so you have an array of words, then for each word, check if it begins and ends with an a - if so, construct a new word by checking the old word's length. Then turn the array back into a single string.
const input = 'aza asssa axxxa rrra';
const words = input.split(' ');
const replacedWords = words.map(word => (
word[0] === 'a' && word[word.length - 1] === 'a' && word.length >= 3
? 'a' + '!'.repeat(word.length - 2) + 'a'
: word
));
const output = replacedWords.join(' ');
console.log(output);

Break Camel Case function in JavaScript

I have been attempting to solve this codewars problem for a while in JavaScript:
"Complete the solution so that the function will break up camel casing, using a space between words. Example:"
"camelCasing" => "camel Casing"
"identifier" => "identifier"
"" => ""
I have it almost all the way, but for some reason my code is selecting the wrong space to add a blank space.
I'm hoping someone can tell me what I am doing wrong.
function solution(string) {
let splitStr = string.split("");
let newStr = string.split("");
let capStr = string.toUpperCase().split("");
for (i = 0; i < splitStr.length; i++) {
if (splitStr[i] === capStr[i]) {
newStr.splice(i, 0, ' ');
}
}
return newStr.join("");
}
console.log('camelCasing: ', solution('camelCasing'));
console.log('camelCasingTest: ', solution('camelCasingTest'));
The first insertion into newStr will be at the correct spot, but after that insertion of the space, the letters that follow it in newStr will be at an increased index. This means that when the next capital is found at i in splitStr (which did not change), the insertion into newStr (which did change) should really be at i+1.
A solution is to make your loop iterate from end to start:
function solution(string) {
let splitStr = string.split("");
let newStr = string.split("");
let capStr = string.toUpperCase().split("");
for (i = splitStr.length - 1; i >= 0; i--) {
if (splitStr[i] === capStr[i]) {
newStr.splice(i, 0, ' ');
}
}
return newStr.join("");
}
console.log('camelCasing: ', solution('camelCasing'));
console.log('camelCasingTest: ', solution('camelCasingTest'));
This kind of problem is however much easier solved with a regular expression:
function solution(string) {
return string.replace(/[A-Z]/g, " $&");
}
console.log('camelCasing: ', solution('camelCasing'));
console.log('camelCasingTest: ', solution('camelCasingTest'));
Explanation of the regular expression:
[A-Z] a capital letter from the Latin alphabet.
$& backreference to the matched letter, used in the replacement.
g global flag so all matches are replaced.
Here could be a solution with a simple loop and some if conditions
const breakCamelCase = (word) => {
let result = "";
// loop on letter
for (let letter of word) {
// if letter is uppercase and not the first letter of the word add a space followed by the letter
if (letter == letter.toUpperCase() && result) {
result += ` ${letter}`;
} else { // else just add the letter
result += letter;
}
}
return result;
}
function solution(string) {
let splitStr = string.split("");
let newStr = "";
splitStr.forEach(e =>{
if(e === e.toUpperCase()) newStr +=" "+e;
else newStr += e;
});
return newStr;
}
console.log(solution('camelCasing'));//success = "camel Casing"
console.log(solution('camelCasingTest'));

How do I write a function in JS to return abbreviation of the words?

For example:
makeAbbr('central processing unit') === 'CPU'
I could not find my mistake. I appreciate your help.
function makeAbbr(words) {
let abbreviation = words[0];
for (let i = 1; i < words.length; i++) {
if (words[i] === '') {
abbreviation += words[i + 1];
}
}
return abbreviation.toUpperCase();
}
console.log(makeAbbr('central processing unit'));
You just need to change the words[i] === '' into words[i] === ' '. '' is an empty string.
Another option is splitting the passed string.
function makeAbbr(str) {
// words is [ "central", "processing", "unit" ]
let words = str.split(/\s+/);
let abbreviation = '';
for (let i = 0; i < words.length; i++) {
abbreviation += words[i][0];
}
return abbreviation.toUpperCase();
}
This will generally work on abbreviation for words that use the first character of each words separated by a space.
function makeAbbr(words) {
// result abbreviation
let abbreviation = '';
// store each word into an array using split by space
let wordArray = words.split(' ');
// iterate through the word array
for (let i = 0; i < wordArray.length; i++) {
// take the first character in each word into the result abbreviation
abbreviation += wordArray[i][0];
}
// return the abbreviation with all of them being upper case
return abbreviation.toUpperCase();
}
// test case
console.log(makeAbbr('central processing unit'));
A one liner solution:
function makeAbbr(words) {
return words.split(' ').map(word => word[0].toUpperCase()).join("");
}
console.log(makeAbbr('central processing unit'));
We are converting the string sentence to an array of words separated by a space (.split(" ")), then mapping or transforming every word in the array to its first letter, as well as capitalizing it: .map(word => word[0].toUpperCase()), then joining the array elements into a string with a "nothing" "" as a separator:
"central processing unit" -> ["central", "processing", "unit"] -> ["C", "P", "U"] -> "CPU"
const sample = ('central processing unit');
const makeAbrr = (word: string) => {
return word.split(' ').map((letter) => letter[0].toUpperCase()).join('');
}
console.log(makeAbrr(sample));
Regex version
function makeAbbr(text) {
if (typeof text != 'string' || !text) {
return '';
}
const acronym = text
.match(/[\p{Alpha}\p{Nd}]+/gu)
.reduce((previous, next) => previous + ((+next === 0 || parseInt(next)) ? parseInt(next): next[0] || ''), '')
.toUpperCase();
return acronym;
}
console.log(makeAbbr('central processing unit'));
Reference

Why won't this iterate?

I am trying to make this Pig Latin function (I just started coding 3 weeks ago, so go easy on me), and I can't figure out why I can't get the array made from .split(' ') and then iterated through to join back again. In the output I only get the first word. The code is below:
function pigLatin(str) {
let str1 = str.split(' ')
for (let i = 0; i < str1.length; i++) {
if (str1[i].length <= 1) {
return str1[i];
}
else {
let first = str1[i].substring(0,1);
let word = str1[i].substring(1);
str = word + first + 'ay';
return str
}
}
}
console.log(pigLatin("This is a test"));
Keep in mind that I was considering adding regex and more else if statements, but I can't even get this to work yet. Any help is greatly appreciated.
You're returning too early. You should be adding each word to an array, and at the end of your loop you should concatenate the words in the array to form a new string which you should return. See my comments for how I altered your code:
function pigLatin(str) {
let r = [] // The array to build
let str1 = str.split(' ')
for (let i = 0; i < str1.length; i++) {
if (str1[i].length <= 1) {
r.push( str1[i] ); // Add to end of array
}
else {
let first = str1[i].substring(0,1);
let word = str1[i].substring(1);
str = word + first + 'ay';
r.push(str) // Add to end of array
}
}
return r.join(' ') // Join strings in array and return new string
}
console.log(pigLatin("This is a test"));

Categories