Find the nth character from an array of words in JavaScript - javascript

I'd like to create a function (nthChar) that takes 1 parameter - an array of n words.
The function should concatenate the nth letter from each word to construct a new word which should be returned as a string.
The nth letter should be the 1st from the first word in the array, the second from the second word in the array, the third from the third and so on. So:
nthChar(['I','am','Tom']) should return 'Imm'
Here's my attempt:
function nthChar(words){
for (var i=0; i<words.length; i++) {
return words[i].charAt(words.indexOf(words[i]))
}
}
Which only seems to grab the first letter of the first word. How would I proceed to the other words of the array before concatenation?

With minimal changes to your code, you can do this
function nthChar(arr) {
var str = '';
for (var i=0; i<words.length; i++) {
str = str + words[i][i];
}
return str;
}
str - used to build up the result string
words[i] selects the i'th word ... the second [i] in that statement selects the i'th letter in that word
for example: "Hello World"[6] is W
Bonus: works in IE8 and earlier ...
and, just for the hell of it, void's answer in ES6
var nthChar = arr => arr.map((i, v) => i[v]).join('');

This can be as simple as
function nthChar(words){
var s = "";
for(var i=0;i<words.length;i++){
s+= words[i].charAt(i);
}
return s;
}
Live example: http://jsfiddle.net/11yc79jn/
This is closest to your original solution, and just uses the loop control variable i which is incrementing already as you loop through the words array. Of course, also return after the entire loop has run as well.

function nthChar(arr){
return arr.map(function(i, v){
return i[v];
}).join("");
}
console.log(nthChar(['I','am','Tom']));
So it is returning an array of the characters you want and then it is joining it. Makes sense?
The issue with your code was that you were not concatenating anything to the output. You can access the characters of a string as if it is an array.
Live Fiddle
Your code can be:
function nthChar(words){
var str = "";
for (var i=0; i<words.length; i++) {
str += words[i].charAt(i);
}
return str;
}
Fiddle

Try something like this
function nthChar(words){
var result = "";
for (var i = 0, ln = words.length; i<ln; i++)
result += words[i].charAt(i);
return result;
}

Related

Function to capitalize first and last letter of each word not working

I created a function that given any string will return the string with the first and last letter of each word capitalized. So far it works in some words, not on others, can someone help me figure out why?
function Capitalize(str) {
var spl = str.split(" ");
var words = [];
for (let i = 0; i < spl.length; i++) {
//For every word
for (let j = 0; j < spl[i].length; j++) {
//For every letter in each word
var word = spl[i];
var size = spl[i].length;
var firstLetterCapital = word.replace(word[0], word[0].toUpperCase()); //Creates new array
var LastLetterCapital = firstLetterCapital.replace(
word[size - 1],
word[size - 1].toUpperCase()
);
}
words.push(LastLetterCapital);
}
console.log(words.join(" "));
}
Capitalize("hello there");
It works when I type : Capitalize("my name is john smith"), but not with Capitalize("hello there")
I know it's a complete mess and probably a very bad way to do it, but I started programming a month ago so give me a break :)
#symlink has already explained why it is "HellO ThEre" instead of "Hello TherE". He also has given a solution to explicitly target first and last character of the string. I have accomplished not much different than already posted by members, except for .. "may be" a little more explanation.
You can break the entire problem in these four steps.
Get all the words into an array.
Create a function, that takes each word and targets first and last character, changes it and returns the changed word.
Apply a mapping step using the function created above (in step 2) to the entire array of words (obtained in step 1).
Join the transformed array, obtained in step 3, using a blank space as a separator.
I have written two functions that accomplish this task. I am sorry for long name of functions. It helps me keep track of things in a complex program (especially when I am in a hurry!).
Step 2 function
function Capitalize_FirstAndLast_One_Word(word){
// Split the string in array for easy access/manipulation by indexing
Split_String = word.split("")
// Target the first word
Split_String[0] = Split_String[0].toUpperCase();
// Target the last word
Split_String[Split_String.length - 1] = Split_String[Split_String.length - 1].toUpperCase();
// Join the array into a single word
Joined_Back = Split_String.join("")
return Joined_Back;
}
Step 1, 3 and 4 function
function Capitalize_Entire_String(str){
Regular_Exp = new RegExp(/\w+/g);
//Below is step 1
MatchedArray = str.match(Regular_Exp);
//Below is step 3
ConvertedArray = MatchedArray.map(Capitalize_FirstAndLast_One_Word);
// Below is step 4
ReturnedString = ConvertedArray.join(" ");
console.log(ReturnedString);
return ReturnedString;
}
Now you have everything. You can use the function like below.
Capitalize_Entire_String("hello there");
Capitalize_Entire_String("hello there this is a test");
Hope this helps. I am sorry if this turned out to be a redundant answer for you.
Reason your code don't work is the use of replace(). replace() will always replace the first character found.
There is absolutely no reason to run a nested loop. You can achieve this using a single loop.
function cap(str){
let spl = str.split(' ');
for(let i = 0; i < spl.length; i++){
let temp = spl[i];
temp = temp[0].toUpperCase() + temp.slice(1)
temp = temp.slice(0,-1) + temp[temp.length - 1].toUpperCase();
spl[i] = temp;
}
return spl.join(' ');
}
console.log(cap("a quick brown fox"))
An easier way is to use map() and template strings.
const cap = str => str
.split(' ')
.map(x => (
x.length === 1 ?
x.toUpperCase() :
`${x[0].toUpperCase()}${x.slice(1,-1)}${x[x.length -1].toUpperCase()}`)
)
.join(' ')
console.log(cap("a quick brown fox"))
To simplify the function, you could split the string into an array, map each word to the desired format, and join it together into a string again.
function Capitalize(str){
return str.split(" ").map((word) => word.charAt(0).toUpperCase() +
(word.length > 2 ? word.substring(1, word.length - 1) : "") +
(word.length > 1 ? word.charAt(word.length - 1).toUpperCase() : "")).join(" ");
}
console.log(Capitalize("i want to capitalize first and last letters"));
Congrats on starting out programming...
You can use this to achieve what you want to do
function capitalizeFirstAndLastLetters (str) {
const words = str.split(" "); // Split the string into words
const modified = [];
for (const word of words) {
if (word.length <= 2) {
modified.push(word.toUpperCase()); // If the word less than 3 characters, the whole word is capitalized
continue;
}
var firstCapital = word[0].toUpperCase(); // word[0] gets the first index of the string (I.e. the first letter of the word)
var lastCapital = word.slice(-1).toUpperCase(); // The slice function slices a portion of the word. slice(-1) gets the last letter
var middlePart = word.slice(1, -1); // slice(1, -1) means start slicing from the second index (I.e. 1) and ignore the last index
modified.push(firstCapital + middlePart + lastCapital);
}
return modified.join(" "); // Join each element in the modified array with a space to get the final string with each words first and last letters capitalized
}
capitalizeFirstAndLastLetters("hello there I am a boy"); // "HellO TherE I AM A BoY"
Try this, it worked for hello world because I guess you want the outcome to be HellO TherE right?:
function capitalize(str) {
var spl = str.split(" ");
var words = [];
for (let i = 0; i < spl.length; i++) {
//For every word
let changedWord = "";
for (let j = 0; j < spl[i].length; j++) {
//For every letter in each word
if(j == 0 || j == spl[i].length - 1) {
changedWord += spl[i][j].toUpperCase();
} else {
changedWord += spl[i][j].toLowerCase();
}
}
words.push(changedWord);
console.log(words);
}
console.log(words.join(" "));
}
capitalize("hello there");
ALSO: Make your functions name start with lowercase letter. Thats just how it is. Starting with uppercase letters usually are Classes. Just a quick tip
Maybe this does what you want, don't want to change much from your code:
function Capitalize(str) {
var spl = str.split(" ");
var words = [];
for (let i = 0; i < spl.length; i++) {
var word = spl[i];
var firstCapital = word[0].toUpperCase(); // get first character after capitalizing
var lastCapital = word.slice(-1).toUpperCase(); // get last character after capitalizing
var midOriginal = word.slice(1, -1);
words.push(firstCapital + midOriginal + lastCapital) // concat 3 parts
}
console.log(words.join(" "));
}
Capitalize("hello there");
This expression:
var LastLetterCapital = firstLetterCapital.replace(
word[size - 1],
word[size - 1].toUpperCase()
);
Is replacing the first occurrence of the character "e" in "There" with an uppercase "E".
Explanation
The replace() function first translates the first param: word[size - 1] to the literal character "e", then replaces the first occurrence of that character with the uppercase "E", resulting in the string "ThEre".
Solution
Use a regular expression as your first parameter instead, to ensure that the last character is targeted, regardless of whether or not that same character shows up anywhere else in the word:
var LastLetterCapital = firstLetterCapital.replace(/.$/, word[size - 1].toUpperCase());
function Capitalize(str) {
var spl = str.split(" ");
var words = [];
for (let i = 0; i < spl.length; i++) {
//For every word
var word = spl[i];
var size = spl[i].length;
for (let j = 0; j < size; j++) {
//For every letter in each word
var firstLetterCapital = word.replace(word[0], word[0].toUpperCase()); //Creates new array
var LastLetterCapital = firstLetterCapital.replace(/.$/, word[size - 1].toUpperCase());
}
words.push(LastLetterCapital);
}
console.log(words.join(" "));
}
Capitalize("hello there");
This should do the trick:
function Capitalize(str) {
return str.replace(/(\b\w|\w\b)/g, l => l.toUpperCase())
}
console.log(Capitalize('i want to be capitalized in a rather strange way'))
Explanation:
In the regular expression /(\b\w|\w\b)/g, \b means "word boundary" and \w means "word character", so (\b\w|\w\b) matches a word boundary followed by a word character OR a word character followed by a word boundary (i.e. the first and last character of words).
The matches of this expression are then passed to the inline function l => l.toUpperCase() (which itself is the second argument to replace) that capitalizes the passed letter.
the string type is immutable, so why don't you try to convert the string to an array like y = word.split('') and do y[0] = word.charAt(0).toUpperCase() and then convert back to string with y.join('')

Write a function which takes a sentence as an input and output a sorted sentence

I need to write a function which takes a sentence as an input and output a sorted sentence. and there are two criteria:
Each character of the word should be arranged in alphabetical order
Words should be arranged in ascending order depending on its character count
Note: - Word only can have lowercase letters
Example :
Inputs str = "she lives with him in a small apartment"
Output = "a in ehs him hitw eilsv allms aaemnprtt"
Here is my code.
function makeAlphabetSentenceSort(str) {
var sens = str.split(' ');
sens.sort(function(a, b) {
return a.length - b.length;
console.log(sens);
});
function alphaSort(b) {
var x = b.split("");
console.log(x.sort().join(""));
}
for (var i = 0; i <= sens.length - 1; i++) {
console.log(alphaSort(sens[i]));
}
}
console.log(makeAlphabetSentenceSort("she lives with him in a small enter code hereapartment"));
I'm confused about how to solve that. Any suggestion, please?
It appears that your code mostly works. I was able to get the correct output by replacing console.log(x.sort().join("")); with return x.sort().join("");
I also had to remove console.log(alphaSort(sens[i])); in favor of storing the loop output in a temp variable called output and then returning the entire loop output as a string.
function makeAlphabetSentenceSort(str) {
var sens = str.split(' ');
sens.sort(function(a, b){
return a.length - b.length;
});
function alphaSort(b){
var x = b.split("");
return x.sort().join("");
}
var output = "";
for(var i = 0; i <= sens.length - 1; i++){
output += alphaSort(sens[i]) + " ";
}
return output.trim();
}
console.log(makeAlphabetSentenceSort("she lives with him in a small apartment"));
I would also for readability rewrite the code as follows:
Remove alphaSort as a function as it does not need to be a function in the current context.
use let keyword instead of var keyword to instantiate output variable.
instantiate output variable at the top of the function (because this is how JS really works)
function makeAlphabetSentenceSort(str) {
let output = "";
// Sort the initial sentence by words alphabetically.
var sens = str.split(' ');
sens.sort(function(a, b){
return a.length - b.length;
});
for(var i = 0; i <= sens.length - 1; i++){
// Split each word into single characters. Sort the characters and
// join them back as a single string.
output += sens[i].split("").sort().join("");
// Because we want the response to look like a sentence.
output += " ";
}
return output.trim();
}
console.log(makeAlphabetSentenceSort("she lives with him in a small apartment"));

JS: Reversing a string using nested loop does not work

I have written a function called reverseStr that takes in a string as a parameter and returns the string but with the characters in reverse.
For example: reverseStr('bootcamp'); => 'pmactoob'
Following is my program:
function reverseStr(str)
{
var splitStr = str.split("");
console.log(splitStr);
var reverseString = [];
for(var i = 0; i <= splitStr.length -1 ; i++)
{
for(var j = splitStr.length - 1; j >= 0; j--)
{
reverseString[i] = splitStr[j]
}
}
return reverseString.toString().replace(/[&\/\\#,+()$~%.'":*?<>{}]/g, '');
}
If I run the function reverseStr("bootcamp") it returns bbbbbbbb.
Does anyone see a problem with the code?
Note: I DONOT WANT TO USE REVERSE() BUILT-IN FUNCTION
However, I found success with the following code but still need an answer to my initial question
function reverseStr(str)
{
var splitStr = str.split("");
reverseStr = "";
for(var i = splitStr.length - 1; i >= 0 ; i = i - 1)
{
reverseStr += splitStr[i];
}
return reverseStr;
}
You don't need to double-iterate through the characters, i.e., do not need to nest for loops. Iterate once and grab the chars in reverse order, like this:
function reverseStr(str)
{
var splitStr = str.split("");
console.log(splitStr);
var reverseString = [];
for(var i = 0, j=splitStr.length-1; i <= splitStr.length -1 ; i++, j--)
{
reverseString[i] = splitStr[j]
}
return reverseString.toString().replace(/[&\/\\#,+()$~%.'":*?<>{}]/g, '');
}
You can see that here the loop goes on for as long as i <= splitStr.length -1,ie, length of the string. This is sufficient to get the mirroring character (i versus Array.length-i).
Here is a working snippet to demo:
var reverseStr = function(str) {
let result = String();
for(let i = str.length-1; i >= 0; i--) {
result += str.charAt(i);
}
return result.replace(/[&\/\\#,+()$~%.'":*?<>{}]/g, '');
}
$('button').click(function() {
$('.result').text(reverseStr($('#str').val()));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="str">
<button>Reverse it</button>
<div class="result"></div>
Perhaps a more elegant way to achieve the same (apart from Array.prototype.reverse()) would be to use String.prototype.chatAt(). This would avoid two conversions to and from an array, and also save you one variable. Granted, the code is much shorter and more obvious in what it is doing.
var reverseStr = function(str) {
let result = String(); // An empty string to store the result
for(let i = str.length-1; i >= 0; i--) { // Iterate backwards thru the chars and add to the result string
result += str.charAt(i);
}
return result.replace(/[&\/\\#,+()$~%.'":*?<>{}]/g, ''); // Original return method of the author
}
$('button').click(function() {
$('.result').text(reverseStr($('#str').val()));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="str">
<button>Reverse it</button>
<div class="result"></div>
The problem is that your nested for loop runs its whole course before it returns to the outer for loop. So, it just repeats one character the amount of times equal to the length. Instead of having another for loop, just add a simple counter for j like j++ inside your outer for loop and use that value with the i value.
To the original poster, consider this:
If you know the length of the original string, you therefore know the offset of that last position within the original string.
Iterate through the original string in reverse order, appending the current position's value to a new string. The new string would be the reverse of the original.
Aydin's example is essentially correct. Here's my very similar version, with comments:
function reverseString(inputString) {
// create a new empty string
var newString = "";
// iterate through the characters of the string in reverse order,
// appending to the new string
for (var i = inputString.length - 1; i >= 0; i--) {
newString += inputString[i];
}
return newString;
}
console.log(reverseString('bootcamp'));

capitalizing only first letter in a contraction

My challenge is to capitalize the first letter of each word in a string while making sure all the other letters are lowercase. I have spent more hours then I'm willing to admit on this and my code is shown below. It's about 95% complete.
It's only flaw is that it returns contractions like "I'm" as "I'M". For some reason it sees contractions as two separate words. I tested this my putting a console.log immediately after the step that capitalizes the first letter (I have commented it out in the example). it returns that it is capitalizing both "I" and "M" in the same step. How do I get get it change only the "I"?
function titleCase(str) {
str = str.toLowerCase(); //make everything lowercase
str = str.split(" "); //make the string to array
for(i = 0; i < str.length; i++){
var strItem = str[i]; //take item in array
strItem = strItem.replace(/\b./g, function(m){ return m.toUpperCase(); }); //capitalize it
//console.log(strItem);
str[i] = strItem; //put changed item back into array
}
str = str.join(" "); //turn array back into string
return str;
}
titleCase("I'm a little tea pot");
Thank you for your time.
Your problem seems to be that you are using a global match in your replacer expression.
Remove the g.
function titleCase(str) {
str = str.toLowerCase(); // Make everything lowercase
str = str.split(/\s+/); // Make the string to array
for (var i = 0; i < str.length; i++) {
var strItem = str[i]; // Take item in array
strItem = strItem.replace(/\b./,
function(m) {
return m.toUpperCase(); // Capitalize it
}
);
str[i] = strItem; // Put changed item back into array
}
return str.join(" "); // Turn array back into string
}
document.body.innerHTML = titleCase("I'm a little tea pot");
Simplified
You can create a capitalCase function and use it as the mapping (callback) function for each word.
function titleCase(str) {
return str.split(/\s+/).map(captitalCase).join(' ');
}
function captitalCase(str) {
return str.charAt(0).toUpperCase() + str.substring(1).toLowerCase();
}
document.body.innerHTML = titleCase("I'm a little tea pot");
Preserve White-Space
If you want to preserve white-space, you can replace all sequences non-white-space characters with their respective capitalCase equivalent.
function titleCase(str) {
return str.replace(/(\S+)/g, function(m) {
return captitalCase(m);
});
}
function captitalCase(str) {
return str.charAt(0).toUpperCase() + str.substring(1).toLowerCase();
}
document.body.innerHTML = titleCase("I'm a little \n tea pot");
body {
white-space: pre;
}
What I suggest, is that you use <string>.charAt(<index>) to get the first letter of a string, and that <string>.slice(<index>) can give you a portion of a string.
Hint: After taking each word, you could take the first letter using charAt(), uppercase it, then take the rest slice of your string and lowercase it.
UPDATE:
Answer:
function upperFirstLetterInWords(str) {
var totalString = "";
//Take words from sentence -
//Use regex /\s+/g for many spaces in sentence.
var words = str.split(" ");
//Take each word...
//Using for loop as we have an array and it is
//more efficient than foreach loop or lambda.
for(var i = 0; i < words.length; ++i) {
//Make your changes here.javascript:;
totalString += words[i].charAt(0).toUpperCase() +
words[i].slice(1).toLowerCase() +
" ";
}
//Remove last space.
return totalString.trim();
}
console.log(upperFirstLetterInWords("I'm A LitTle TEa POt."));
Out of curiosity, I wanted to see if I could come up with an alternative javascript solution without using regex:
var selectedParagraph = document.getElementsByTagName('p')[1];
var textUC = [];
function toTitleCase(element) {
var textLC = element.innerHTML.toLowerCase().split(' ');
for (var i = 0; i < textLC.length; i++) {
textUC[i] = textLC[i].substr(0,1).toUpperCase() + textLC[i].substr(1);}
element.innerHTML = textUC.join(' ');
}
window.onload = toTitleCase(selectedParagraph);
<p>I'm a little tea pot</p>
<p>I'm a little tea pot</p>

converting a string to numbers Javascript

I've starting messing up with javascript lately and stumbled upon some problem.
I'm allowing my user to insert a series of numbers separated by white-spaces into a text field. I am trying to read the string from the text field and store the numbers in an array. However, I have those 0's added unwillingly. I went thru my code over and over, yet I cannot find whats wrong.
the code:
function get_input(str)
{
var arr = [];
var elem=0;
for(var i=0,j=1; i<str.length ;i++,j++)
{
if (j == str.length) {elem += str[i];
arr.push(elem);
return arr;}
else if (str[j]== " ")
{
elem *=10;
elem +=str[i];
arr.push(elem);
elem=0;
i++;
j++
}
else
{
elem *=10;
elem += str[i];
}
}
return arr;
}
e.g for an input:123 45 6
the output is : 10203*405*06*
I put the * only to see the elements in the array,
Help will be much appreciated.
function get_input(str){
var a = str.split(' ');
for(var i = 0; i < a.length; i++){
a[i] = parseFloat(a[i]);
}
return a;
}
Break-down:
Using the split method, we're populating an array with the strings separated by the ' ' (space) delimiter.
We then cycle through the array in order to parse the results into Numbers. If this isn't needed (i.e you're happy with the digits being represented as Strings) then you don't need that extra step.
We then return the array.

Categories