I want to change to make the first letters of the words in the string uppercase, and after translating into an array, I use the map method. The problem is that inheritance does not work in this method, as I understand it, because when you return the map element, the original string is returned:
const str = 'dkdg gkdj wijoerbj'
let r = str.split(' ').map((item, index) => {
item[0] = item[0].toUpperCase()
return item
})
unchanged first letters will also be returned with such a code entry(is in the map()):
item[0] = item[0].toUpperCase()
return item[0]
however, when I return the first line, the letters still become uppercase, but I do not know how to return the rest of the word in this case(is in the map()):
return item[0] = item[0].toUpperCase()
why inheritance does not work as it should, tell me, please, and how to add the rest of the word if there are no other options?
You need to cancat the first letter with rest of the string. Also these two lines item[0] = item[0].toUpperCase();return item though will convert the first letter to uppercase but it will still return the original sting because item represent the original word nut not the modified text
const str = 'dkdg gkdj wijoerbj'
let r = str.split(' ').map((item, index) => {
return item.charAt(0).toUpperCase() + item.substring(1, item.length)
});
console.log(r)
We can do this with two array map methods as bellow.
const str = 'dkdg gkdj wijoerbj';
let r = str.split(' ').map((item, index) => {
return ([...item].map((letter, i) => {
return (i == 0) ? letter.toUpperCase() : letter;
})).join('');
});
console.log(r);
const str = 'dkdg gkdj wijoerbj'
let r = str.split(' ').map(x=> x[0].toLocaleUpperCase());
console.log(r)
u can try this code to get first letters of the words in the string uppercase into new arry using map and returns capital letter of each first letter
Related
I'm trying to add commas in between the first and last names in parentheses.
//Input:
s = "Fred:Corwill;Wilfred:Corwill;Barney:Tornbull;Betty:Tornbull;Bjon:Tornbull;Raphael:Corwill;Alfred:Corwill";
//Expected output: "(CORWILL, ALFRED)(CORWILL, FRED)(CORWILL, RAPHAEL)(CORWILL, WILFRED)(TORNBULL, BARNEY)(TORNBULL, BETTY)(TORNBULL, BJON)"
What my code is currently outputting:
(CORWILL ALFRED) (CORWILL FRED) (CORWILL RAPHAEL) (CORWILL WILFRED) (TORNBULL BARNEY) (TORNBULL BETTY) (TORNBULL BJON)
I've tried a number of approaches like changing how the characters are replaced in the beginning when I reassign s (the string) so that I am not removing the commas in the first place, to then have to replace them...but when I did that, the regex I have was no longer working, and I am not sure why that is. So I tried to find another regex to use so I could work around that problem, but that has equally been a pain, so I decided to just stick to solving it this way: trying to find a way to find commas in between the first, and last names in the parentheses.
Full problem & code:
/*Could you make a program that
• makes this string uppercase
• gives it sorted in alphabetical order by last name.
When the last names are the same, sort them by first name. Last name and first name of a guest come in the result between parentheses separated by a comma.
*/
function meeting(s) {
s = s.replace(/:/g, ", ").toUpperCase();
//order alphabetically based on Last, then first name
const semicolon = ';'
let testArr = s.split(semicolon)
testArr.sort(function compare(a, b) {
var splitA = a.split(",");
var splitB = b.split(",");
var firstA = splitA[0]
var firstB = splitB[0]
var lastA = splitA[splitA.length - 1];
var lastB = splitB[splitB.length - 1];
if (lastA < lastB) return -1;
if (lastA > lastB) return 1;
if (firstA < firstB) return -1; //sort first names alphabetically
if (firstA > firstB) return 1;
return 0; //if they are equal
})
//print last names before first names with regex
let newArr = [];
for (let i = 0; i < testArr.length; i++) {
let variable = (testArr[i].replace(/([\w ]+), ([\w ]+)/g, "$2 $1"))
let comma = ","
newArr.push(`(${variable})`)
}
let finalStr;
finalStr = newArr.toString().replace(/[ ,.]/g, " ").toUpperCase();
// finalStr = finalStr.replace(/" "/g, ", ")
return finalStr
}
s = "Fred:Corwill;Wilfred:Corwill;Barney:Tornbull;Betty:Tornbull;Bjon:Tornbull;Raphael:Corwill;Alfred:Corwill";
console.log(meeting(s))
// expected result: "(CORWILL, ALFRED)(CORWILL, FRED)(CORWILL, RAPHAEL)(CORWILL, WILFRED)(TORNBULL, BARNEY)(TORNBULL, BETTY)(TORNBULL, BJON)"
Any help would be appreciated, I've spent about 5 hours on this problem.The regex I am using is to switch the last name's position with the first name's position (Fred Corwill) --> (Corwill Fred). If there is a regex for me to this other than the one I am using that you could suggest, maybe I could work around the problem this way too, so far everything I have tried has not worked other the one I am using here.
That looks much more complicated than it needs to be. After splitting by ;s, map each individual element to its words in reverse order, then join:
const s = "Fred:Corwill;Wilfred:Corwill;Barney:Tornbull;Betty:Tornbull;Bjon:Tornbull;Raphael:Corwill;Alfred:Corwill";
const output = s
.toUpperCase()
.split(';')
.sort((a, b) => {
const [aFirst, aLast] = a.split(':');
const [bFirst, bLast] = b.split(':');
return aLast.localeCompare(bLast) || aFirst.localeCompare(bFirst);
})
.map((name) => {
const [first, last] = name.split(':');
return `(${last}, ${first})`;
})
.join('');
console.log(output);
That's what you need:
const str = 'Fred:Corwill;Wilfred:Corwill;Barney:Tornbull;Betty:Tornbull;Bjon:Tornbull;Raphael:Corwill;Alfred:Corwill';
function formatString(string) {
const modifiedString = string.toUpperCase().replace(/(\w+):(\w+)/g, '($2, $1)');
const sortedString = modifiedString.split(';').sort().join('');
return sortedString;
}
console.log(formatString(str))
Using splits with maps and sorts
var s = "Fred:Corwill;Wilfred:Corwill;Barney:Tornbull;Betty:Tornbull;Bjon:Tornbull;Raphael:Corwill;Alfred:Corwill";
var res = s.split(/;/) // split into people
.map(x => x.split(/:/).reverse()) // split names, put last first
.sort((a, b) => a[0] === b[0] ? a[1].localeCompare(b[1]) : a[0].localeCompare(b[0])) // sort by last name, first name
.map(x => `(${x.join(', ')})`) // create the new format
.join(' ') // join the array back into a string
console.log(res);
I have a string like "this/ is an example abc/def/fgh/uio to give you an example"
I'd like to target the longest word and replace on this substring any "/" by a "+".
I manage to identify the longest word and I would know how to replace ALL "/" by a "+" BUT I don't know how to replace the "/" only in the longest word.
Here's what I've got so far
//identify longest word in string
function longestWord(str) {
var words = str.split(' ');
return words.reduce(longer);
}
function longer(champ, contender) {
return (contender.length > champ.length) ? contender: champ;
}
//purely given an exemple, some strigns won't be exactly like this
var text2 = "this/ is an example abc/def/fgh/uio to give you an example"
if (longestWord(text2) > 30 ) {
text2.replace(/\//g, ' / ');
}
The problem is this will also replace the "/" on the substring "this/", and I don't want that.
How to achieve this?
Your longestWord function returns the longest word in the string, so you can pass that string alone (not a regular expression) as the first argument to .replace, and replace with (the second argument) the /\//g called on that longest word:
function getLongestWord(str) {
var words = str.split(' ');
return words.reduce(longer);
}
function longer(champ, contender) {
return (contender.length > champ.length) ? contender: champ;
}
var text2 = "this/ is an example abc/def/fgh/uio to give you an example"
const longestWord = getLongestWord(text2);
const output = text2.replace(longestWord, longestWord.replace(/\//g, '+'));
console.log(output);
#CertainPermance's solution is far more elegant (and I think performant) than this, but as I'd written the answer I thought I may as well put it in.
It's fairly similar, in truth, though in this instance we get the index of the word and use that to perform the replace, which at the time of writing I thought was necessary. Now looking at the better solution, I realise such a check is not needed, as the longest word in a string will not feature in any other words, so it's easy and safe to simply perform a replace on it.
const data = "this/ is an example abc/def/fgh/uio to give you an example";
const getLongestWordIndex = stringIn => stringIn
.split(' ')
.reduce(
(prev, curr, i) => curr.length > prev.length ? {
index: i,
length: curr.length
} : prev,
{
length: -1,
index: -1
}
).index
const replaceLongestWord = (sentence, replacer) => {
const longestWordIndex = getLongestWordIndex(sentence);
const words = data.split(' ');
return Object.values({
...words,
[longestWordIndex]: replacer(words[longestWordIndex])
}).join(' ')
}
const wordReplaceFunction = word => word.replace(/\//g, '+')
const result = replaceLongestWord(data, wordReplaceFunction);
console.dir(result)
I am trying to sort a string which contains a single number from 1-9. For e.g. string is "Ho2w are1 y3ou" then resulting string should be "are1 Ho2w y3ou". For that, I have used for...of loop to iterate over a string and used split to convert it into an array of string and then used sort method but I am not getting an output. Can anyone suggest what's wrong in my program?
code ::
function order(words){
let result = "";
for (let value of words) {
result += value;
}
let splited = result.split(" ");
if(words === ""){
return "";
}
return splited.sort((a,b) => a - b);
}
order("Ho2w are1 y3ou");
You need to somehow find the number in the word that you want to use to sort. One way to do this is with String.match() and a regular expression:
let str = "Ho2w are1 y3ou"
let sorted =
str.split(' ')
.sort((a,b) => a.match(/\d+/)[0] - b.match(/\d+/)[0]) // sort based on first number found
.join(' ')
console.log(sorted)
You can use the regexp /\s+/ for splitting the array, that way you can match the tab too. And the regexp [^\d+]/g to remove those chars which are not a number and make the comparison with numbers only.
let str = "Ho2w are1 y3ou"
let sorted = str.split(/\s+/)
.sort((a, b) => a.replace(/[^\d+]/g, '') - b.replace(/[^\d+]/g, '')).join(' ');
console.log(sorted);
You can also extract characters using filter and isNaN and then use parseInt to get their integer value to use for your sorting function.
const str = "are1 Ho2w y3ou";
const ordered = str.split(" ").sort((a, b) => {
let numA = parseInt([...a].filter(c => !isNaN(c)).join(''));
numB = parseInt([...b].filter(c => !isNaN(c)).join(''));
return numA - numB;
}).join(' ');
console.log(ordered);
i have object with keys and values , i want to pass this object to replace function and replace key with value
function highlight(){
var mapObj = {} //this is the obj to pass to replace
//get the input value
var whatInTextInput = document.querySelector(".toGetText").value;
//trim and split the string into array of words
var whatInTextInput_words_array = whatInTextInput.trim().split(' ');
//build the object with keys and value
for(let item in whatInTextInput_words_array){
mapObj[whatInTextInput_words_array[item]] = "<mark class='highlight'>"+[whatInTextInput_words_array[item]]+"</mark>"
}
// this is just the test string
var str = "I have a cat, a dog, and a goat.";
//here how to pass mapObj instead of /cat|dog|goat/gi ???
str = str.replace(/cat|dog|goat/gi, function(key) {
return mapObj[key];
});
//show the final result
document.querySelector(".inputText").innerHTML = str;
}
.highlight {
background: yellow;
}
<button onclick="highlight()">Highlight</button>
<input type="text" class="toGetText"/>
<div class="inputText">I have a cat, a dog, and a goat.</div>
And if i didn't type the other words i got undefined as a result.
How to pass mapObj obj which has keys and value to replace function, instead of const value /cat|dog|goat/?
You're going to have to get the words from your user input and build a regex from them. .replace simply takes a regex; it does not deal with objects directly.
There are some subtle points here: You'll need to escape any regex meta-characters, and you need to make sure any keys that are prefixes of other keys are listed later (e.g. if you have both cat and caterpillar, the regex needs to be caterpillar|cat, not cat|caterpillar, or else caterpillar will never match).
It's not a good idea to have a mapping object in this case, either: You want to do case insensitive matching, so you can't just pre-compute a replacement string: If you don't normalize your matched strings, you'll just get undefined (because e.g. CaT isn't among the keys), and if you do, you'll destroy the original case of the text (e.g. CaT would turn into <mark class="highlight">cat</mark> (all lowercase)).
The easiest solution is to take all words from the input string, sort them by descending length (to ensure any prefix strings are listed later), escape all regex metacharacters, and join them with |. However, if the input list is empty, that would result in '' (a string that matches everywhere), and we want it to match nowhere, so just use /^(?!)/ in that case (a regex that never matches).
Then get the .textContent of the target element, do the replacement (computing the replacement HTML dynamically to preserve the original case, and making sure to escape all HTML metacharacters properly), and put it back into .innerHTML.
Somewhat like this:
function highlight() {
const mapObj = {};
const whatInTextInput = document.querySelector(".toGetText").value;
const whatInTextInput_words_array = whatInTextInput.match(/\S+/g) || [];
const regex_str = whatInTextInput_words_array.sort(function (a, b) {
const na = a.length, nb = b.length;
return (
na > nb ? -1 :
na < nb ? 1 :
a < b ? -1 :
b < a ? 1 :
0
);
})
.map(s => s.replace(/\W/g, "\\$&"))
.join('|');
const regex = whatInTextInput_words_array.length ? new RegExp(regex_str, 'gi') : /^(?!)/;
const inputText = document.querySelector('.inputText');
const str = inputText.textContent;
inputText.innerHTML = str.replace(regex, function (word) {
return (
'<mark class="highlight">' +
word.replace(/[<>&]/g, c => '&#' + c.charCodeAt(0) + ';') + // hacky HTML escape
'</mark>'
);
});
}
.highlight {
background: yellow;
}
<button onclick="highlight()">Highlight</button>
<input type="text" class="toGetText"/>
<div class="inputText">
I have a cat, a dog, and a goat.
</div>
I'm aware of the CSS attribute text-transform: capitalize but can anyone help me with replicating this using Javascript?
I would like to pass an argument to my function which will return the string with the first letter of each word capitalized.
I've got this far but I'm stuck trying to break my array of strings in to chunks:
function upper(x){
x = x.split(" ");
// this function should return chunks but when called I'm getting undefined
Array.prototype.chunk = function ( n ) {
return [ this.slice( 0, n ) ].concat( this.slice(n).chunk(n) );
};
x = x.chunk;
}
upper("chimpanzees like cigars")
after the chunk I'm guessing I need to again split each chunk in to the first character and the remaining characters, use .toUpperCase() on the first character, join it back up with the remaining and then join up the chunks again in to a string?
Is there a simpler method for doing this?
I came up with a solution for both a single word and also for an array of words. It will also ensure that all other letters are lowercase for good measure. I used the Airbnb style guide as well. I hope this helps!
const mixedArr = ['foo', 'bAr', 'Bas', 'toTESmaGoaTs'];
const word = 'taMpa';
function capitalizeOne(str) {
return str.charAt(0).toUpperCase().concat(str.slice(1).toLowerCase());
}
function capitalizeMany(args) {
return args.map(e => {
return e.charAt(0).toUpperCase().concat(e.slice(1).toLowerCase());
});
};
const cappedSingle = capitalizeOne(word);
const cappedMany = capitalizeMany(mixedArr);
console.log(cappedSingle);
console.log(cappedMany);
The map function is perfect for this.
w[0].toUpperCase() : Use this to capitalize the first letter of each word
w.slice(1): Return the string from the second character on
EDGE Case
If the user doesn't enter a string, the map function will not work and an error will be raised. This can be guarded against by checking if the user actually entered something.
var userInput = prompt("Enter a string");
var capitalizedString = userInput == "" ? "Invalid String" :
userInput.split(/\s+/).map(w => w[0].toUpperCase() + w.slice(1)).join(' ');
console.log(capitalizedString);
You can use the following solution which doesn't use regex.
function capitalize(str=''){
return str.trim().split('')
.map((char,i) => i === 0 ? char.toUpperCase() : char )
.reduce((final,char)=> final += char, '' )
}
capitalize(' hello') // Hello
"abcd efg ijk lmn".replace(/\b(.)/g, (m => m.toUpperCase())) // Abcd Efg Ijk Lmn
You may want to try a regex approach:
function upperCaseFirst(value) {
var regex = /(\b[a-z](?!\s))/g;
return value ? value.replace(regex, function (v) {
return v.toUpperCase();
}) : '';
}
This will grab the first letter of every word on a sentence and capitalize it, but if you only want the first letter of the sentence, you can just remove the g modifier at the end of the regex declaration.
or you could just iterate the string and do the job:
function capitalize(lowerStr){
var result = "";
var isSpacePrevious = false;
for (var i=0; i<lowerStr.length; i++){
if (i== 0 || isSpacePrevious){
result += lowerStr[i].toUpperCase();
isSpacePrevious = false;
continue;
}
if (lowerStr[i] === ' '){
isSpacePrevious = true;
}
result += lowerStr[i];
}
return result;
}