JS: Reversing a string using nested loop does not work - javascript

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'));

Related

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"));

Why Javascript console.log result is undefined while reversing the string?

var a = "gsdgtrshghf";
function reverseString(strr){
if (!strr.length){
var result="";
for(var i=strr.length;i>0;i++){
var a=strr.chatAt(i);
result+=a;
}
}return result;
}
console.log(reverseString(a))
When I tried to run it it returned me "undefined". I wonder what's the problem here.
The main reason is you are declaring var result="" and returning from outside of if(so it become undefined as its scope is only inside if statement) and other errors areas mention in comments you have a typo, charAt not chatAt. You can also simply use strr[i] to get the char. Also, you should do i-- and i >= 0 if you start at strr.length, otherwise for loop is immediately completed at the condition check. Check the below code.
var a = "gsdgtrshghf";
function reverseString(strr){
var result="";
if (strr.length){
for(var i=strr.length-1;i>=0;i--){
var a=strr.charAt(i);
result+=a;
}
}
return result;
}
console.log(reverseString(a))
Have a look:
var a = "gsdgtrshghf";
function reverseString(strr) {
var result = "";
if (strr.length != null) {
for (var i = strr.length - 1; i >= 0; i--) {
var a = strr.charAt(i);
result += a;
}
}
return result;
}
console.log(reverseString(a));
// Better
const reverse = str => Array.from(str).reverse().join('');
console.log(reverse('foo 饾寙 bar ma帽ana man虄ana'));
Explanation
It's charAt(i) not chatAt(i)
Loop should start from length - 1 and end at 0 and i should be decremented
And finally declare the variable outside of if
i.e for(var i = strr.length - ; i >= 0; i--){
not for(var i=strr.length;i>0;i++){
Better yet, use combo of Array.from(str).reverse().join(''), as it even works with Unicode characters, as pointed out in comments by gaetanoM

Splice NOT removing certain characters

I'm working on some codewars problems and I came to this 'remove noise thing', I guess the point is to escape backslash \ and use replace method, which was easy. But I didn't want to use replace, instead I found myself in trouble trying to remove items with splice method.
Funny thing is, when I debug in Chrome dev tools, step by step I see items get removed, but console.log spits out certain characters($/路|陋l) problematic to remove, and at the end gets returned and join with those characters. Why is that?
function removeNoise(str) {
var base = "%$&/#路#|潞\陋";
var arr = str.split('');
for(var i = 0; i < arr.length; i++) {
var item = arr[i];
var condition = base.indexOf(item);
if(condition + 1) {
//works like a charm
//arr[i] = '';
arr.splice(i,1);
//this thing wont work
//when debugging it removes the items from the array
//console log print no removing
}
}
return arr.join('');
}
removeNoise('he%$&/#路#|潞\陋\llo'); //=> $/路|陋llo
You're using splice to remove entries from your array, but you're then incrementing i for the next loop. If you remove the entry at index 5 from a 10-entry array, what was the entry at index 6 is now at index 5 (of what's now a 9-entry array), so you don't want to increment your index.
The solution is to use a while loop and only update i if you don't splice:
function removeNoise(str) {
var base = "%$&/#路#|潞\陋";
var arr = str.split('');
var i = 0;
while (i < arr.length) {
var item = arr[i];
var condition = base.indexOf(item);
if (condition + 1) {
// Remove this entry, reuse same value for 'i'
arr.splice(i,1);
} else {
// Don't remove this entry, move to next
++i;
}
}
return arr.join('');
}
var result = removeNoise('he%$&/#路#|潞\陋\llo');
var pre = document.createElement('pre');
pre.appendChild(
document.createTextNode(result)
);
document.body.appendChild(pre);
You're removing characters from your array. This will throw your indexer variable i out of sync with the characters you want to test. Easy way to fix is to start at the end of the array working your way to the beginning.
Change your for loop to this.
for(var i = arr.length -; i <= 0; i--) {
function removeNoise(str) {
var base = "%$&/#路#|潞\陋";
var arr = str.split('');
for(var i = arr.length - 1; i <= 0 ; i--) {
var item = arr[i];
if(base.indexOf(item) >= 0) {
//remove the offending character
arr.splice(i,1);
}
}
return arr.join('');
}
removeNoise('he%$&/#路#|潞\陋\llo'); //=> $/路|陋llo

Find the nth character from an array of words in 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;
}

Using search method from string

I'm trying to count the number of times certain words appear in the strings. Every time I run it I get a
uncaught TypeErro: undefined is not a function
I just actually need to count the number of times each "major" appears.
Below is my code:
for(var i = 0; i < sortedarray.length; i++)
{
if(sortedarray.search("Multimedia") === true)
{
multimedia += 1;
}
}
console.log(multimedia);
Here is my csv file which is stored in a 1d array.
"NAME","MAJOR","CLASS STANDING","ENROLLMENT STATUS"
"Smith, John A","Computer Science","Senior","E"
"Johnson, Brenda B","Computer Science","Senior","E"
"Green, Daisy L","Information Technology","Senior","E"
"Wilson, Don A","Information Technology","Junior","W"
"Brown, Jack J","Multimedia","Senior","E"
"Schultz, Doug A","Network Administration","Junior","E"
"Webber, Justin","Business Administration","Senior","E"
"Alexander, Debbie B","Multimedia","Senior","E"
"St. John, Susan G","Information Technology","Junior","D"
"Finklestein, Harold W","Multimedia","Freshman","E"
You need to search inside each string not the array. To only search inside the "Major" column, you can start your loop at index 1 and increment by 4 :
var multimedia = 0;
for(var i = 1; i < sortedarray.length; i += 4)
{
if(sortedarray[i].indexOf("Multimedia") > -1)
{
multimedia += 1;
}
}
console.log(multimedia);
What you're probably trying to do is:
for(var i = 0; i < sortedarray.length; i++)
{
if(sortedarray[i].indexOf("Multimedia") !== -1)
{
multimedia++;
}
}
console.log(multimedia);
I use indexOf since search is a bit of overkill if you're not using regexes.
Also, I replaced the += 1 with ++. It's practically the same.
Here's a more straightforward solution. First you count all the words using reduce, then you can access them with dot notation (or bracket notation if you have a string or dynamic value):
var words = ["NAME","MAJOR","CLASS STANDING","ENROLLMENT STATUS"...]
var count = function(xs) {
return xs.reduce(function(acc, x) {
// If a word already appeared, increment count by one
// otherwise initialize count to one
acc[x] = ++acc[x] || 1
return acc
},{}) // an object to accumulate the results
}
var counted = count(words)
// dot notation
counted.Multimedia //=> 3
// bracket notation
counted['Information Technology'] //=> 3
I don't know exactly that you need this or not. But I think its better to count each word occurrences in single loop like this:
var occurencesOfWords = {};
for(var i = 0; i < sortedarray.length; i++)
{
var noOfOccurences = (occurencesOfWords[sortedarray[i]]==undefined?
1 : ++occurencesOfWords[sortedarray[i]]);
occurencesOfWords[sortedarray[i]] = noOfOccurences;
}
console.log(JSON.stringify(occurencesOfWords));
So you'll get something like this in the end:
{"Multimedia":3,"XYZ":2}
.search is undefined and isn't a function on the array.
But exists on the current string you want to check ! Just select the current string in the array with sortedarray[i].
Fix your code like that:
for(var i = 0; i < sortedarray.length; i++)
{
if(sortedarray[i].search("Multimedia") === true)
{
multimedia += 1;
}
}
console.log(multimedia);

Categories