How do I run a function over and over by using parameters? - javascript

My case:
function randomLetter(){
var random = letter[Math.floor(Math.random()*26)];
return random;
}
function randomWord(wordLength){
var random = randomLetter() + randomLetter() + randomLetter();
return random;
}
How do I write a code that run the randomLetter() function x times using parametes.
Example: I write 3 in the parameter, and the function will give me three random letters.
So instead of writing randomLetter() + randomLetter() + randomLetter(), I will just write randomWord(3), and I will get three random letters.

Another approach, which buffers each letter into an array and returns the joined array.
function randomWord(wordLength){
var letters = [];
for (var i = 0; i < wordLength; i++) {
letters.push(randomLetter());
}
return letters.join("");
}

Or recursion:
var letters = "abcdefghijklmnopqrstuvwxyz"
function randomLetter() {
return letters.charAt(Math.floor((Math.random() * 100)) % letters.length)
}
function getLetters(count) {
if (count-- < 1) return "";
return getLetters(count) + randomLetter() + ","
}
document.getElementById("output").innerText = getLetters(4)
<div id="output" />

For this you could use a for loop like:
function randomWord(wordLength){
var random =''
for (var i = 0, i<wordLength, i++) {
random += randomLetter();
}
return random;
}
the first parameter in the parentheses after the 'for' keyword initializes the i variable with 0. The next value i<wordLength is the stop condition, which will test at the beginning of each run if the condition is still true, otherwise it will stop looping. The third i++ is what runs every time a loop finishes, in this case it increments i by one, which is identical to i = i + 1.
here is some more information: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Loops_and_iteration

You can use a for-loop:
function randomWord(x){
var random = [];
for(var a = 0; a < x; a++){
random[a] = randomLetter();
}
return random.join("");
}

Yet another recursive solution:
function randomLetter() {
return ('qwertyuiopasdfghjklzxcvbnm')[Math.floor(Math.random()*26)];
}
function randomWord(wordLength) {
return (wordLength > 0) ? (randomWord(wordLength - 1) + randomLetter()) : '';
}
console.log( randomWord(10) );

Related

How can I extract all contained characters in a String? [duplicate]

I have a string with repeated letters. I want letters that are repeated more than once to show only once.
Example input: aaabbbccc
Expected output: abc
I've tried to create the code myself, but so far my function has the following problems:
if the letter doesn't repeat, it's not shown (it should be)
if it's repeated once, it's show only once (i.e. aa shows a - correct)
if it's repeated twice, shows all (i.e. aaa shows aaa - should be a)
if it's repeated 3 times, it shows 6 (if aaaa it shows aaaaaa - should be a)
function unique_char(string) {
var unique = '';
var count = 0;
for (var i = 0; i < string.length; i++) {
for (var j = i+1; j < string.length; j++) {
if (string[i] == string[j]) {
count++;
unique += string[i];
}
}
}
return unique;
}
document.write(unique_char('aaabbbccc'));
The function must be with loop inside a loop; that's why the second for is inside the first.
Fill a Set with the characters and concatenate its unique entries:
function unique(str) {
return String.prototype.concat.call(...new Set(str));
}
console.log(unique('abc')); // "abc"
console.log(unique('abcabc')); // "abc"
Convert it to an array first, then use Josh Mc’s answer at How to get unique values in an array, and rejoin, like so:
var nonUnique = "ababdefegg";
var unique = Array.from(nonUnique).filter(function(item, i, ar){ return ar.indexOf(item) === i; }).join('');
All in one line. :-)
Too late may be but still my version of answer to this post:
function extractUniqCharacters(str){
var temp = {};
for(var oindex=0;oindex<str.length;oindex++){
temp[str.charAt(oindex)] = 0; //Assign any value
}
return Object.keys(temp).join("");
}
You can use a regular expression with a custom replacement function:
function unique_char(string) {
return string.replace(/(.)\1*/g, function(sequence, char) {
if (sequence.length == 1) // if the letter doesn't repeat
return ""; // its not shown
if (sequence.length == 2) // if its repeated once
return char; // its show only once (if aa shows a)
if (sequence.length == 3) // if its repeated twice
return sequence; // shows all(if aaa shows aaa)
if (sequence.length == 4) // if its repeated 3 times
return Array(7).join(char); // it shows 6( if aaaa shows aaaaaa)
// else ???
return sequence;
});
}
Using lodash:
_.uniq('aaabbbccc').join(''); // gives 'abc'
Per the actual question: "if the letter doesn't repeat its not shown"
function unique_char(str)
{
var obj = new Object();
for (var i = 0; i < str.length; i++)
{
var chr = str[i];
if (chr in obj)
{
obj[chr] += 1;
}
else
{
obj[chr] = 1;
}
}
var multiples = [];
for (key in obj)
{
// Remove this test if you just want unique chars
// But still keep the multiples.push(key)
if (obj[key] > 1)
{
multiples.push(key);
}
}
return multiples.join("");
}
var str = "aaabbbccc";
document.write(unique_char(str));
Your problem is that you are adding to unique every time you find the character in string. Really you should probably do something like this (since you specified the answer must be a nested for loop):
function unique_char(string){
var str_length=string.length;
var unique='';
for(var i=0; i<str_length; i++){
var foundIt = false;
for(var j=0; j<unique.length; j++){
if(string[i]==unique[j]){
foundIt = true;
break;
}
}
if(!foundIt){
unique+=string[i];
}
}
return unique;
}
document.write( unique_char('aaabbbccc'))
In this we only add the character found in string to unique if it isn't already there. This is really not an efficient way to do this at all ... but based on your requirements it should work.
I can't run this since I don't have anything handy to run JavaScript in ... but the theory in this method should work.
Try this if duplicate characters have to be displayed once, i.e.,
for i/p: aaabbbccc o/p: abc
var str="aaabbbccc";
Array.prototype.map.call(str,
(obj,i)=>{
if(str.indexOf(obj,i+1)==-1 ){
return obj;
}
}
).join("");
//output: "abc"
And try this if only unique characters(String Bombarding Algo) have to be displayed, add another "and" condition to remove the characters which came more than once and display only unique characters, i.e.,
for i/p: aabbbkaha o/p: kh
var str="aabbbkaha";
Array.prototype.map.call(str,
(obj,i)=>{
if(str.indexOf(obj,i+1)==-1 && str.lastIndexOf(obj,i-1)==-1){ // another and condition
return obj;
}
}
).join("");
//output: "kh"
<script>
uniqueString = "";
alert("Displays the number of a specific character in user entered string and then finds the number of unique characters:");
function countChar(testString, lookFor) {
var charCounter = 0;
document.write("Looking at this string:<br>");
for (pos = 0; pos < testString.length; pos++) {
if (testString.charAt(pos) == lookFor) {
charCounter += 1;
document.write("<B>" + lookFor + "</B>");
} else
document.write(testString.charAt(pos));
}
document.write("<br><br>");
return charCounter;
}
function findNumberOfUniqueChar(testString) {
var numChar = 0,
uniqueChar = 0;
for (pos = 0; pos < testString.length; pos++) {
var newLookFor = "";
for (pos2 = 0; pos2 <= pos; pos2++) {
if (testString.charAt(pos) == testString.charAt(pos2)) {
numChar += 1;
}
}
if (numChar == 1) {
uniqueChar += 1;
uniqueString = uniqueString + " " + testString.charAt(pos)
}
numChar = 0;
}
return uniqueChar;
}
var testString = prompt("Give me a string of characters to check", "");
var lookFor = "startvalue";
while (lookFor.length > 1) {
if (lookFor != "startvalue")
alert("Please select only one character");
lookFor = prompt(testString + "\n\nWhat should character should I look for?", "");
}
document.write("I found " + countChar(testString, lookFor) + " of the<b> " + lookFor + "</B> character");
document.write("<br><br>I counted the following " + findNumberOfUniqueChar(testString) + " unique character(s):");
document.write("<br>" + uniqueString)
</script>
Here is the simplest function to do that
function remove(text)
{
var unique= "";
for(var i = 0; i < text.length; i++)
{
if(unique.indexOf(text.charAt(i)) < 0)
{
unique += text.charAt(i);
}
}
return unique;
}
The one line solution will be to use Set. const chars = [...new Set(s.split(''))];
If you want to return values in an array, you can use this function below.
const getUniqueChar = (str) => Array.from(str)
.filter((item, index, arr) => arr.slice(index + 1).indexOf(item) === -1);
console.log(getUniqueChar("aaabbbccc"));
Alternatively, you can use the Set constructor.
const getUniqueChar = (str) => new Set(str);
console.log(getUniqueChar("aaabbbccc"));
Here is the simplest function to do that pt. 2
const showUniqChars = (text) => {
let uniqChars = "";
for (const char of text) {
if (!uniqChars.includes(char))
uniqChars += char;
}
return uniqChars;
};
const countUnique = (s1, s2) => new Set(s1 + s2).size
a shorter way based on #le_m answer
let unique=myArray.filter((item,index,array)=>array.indexOf(item)===index)

javascript, returning true when it's false whenever I would try to calculate the average of parameters

function passingAverage(n){
var average = 0, i;
for (i=0; i < n.length; i+= 1){
average += n[i];
}
if ((average/n.length)<49)
return false;
else
return true;
}
in this code, I compare the numbers given in the console.log and just calculate for average.
console.log('passingAverage(75,42,98) returns: ' + passingAverage(75,42,98));
console.log('passingAverage(34,93,77,89,49) returns: ' + passingAverage(34,93,77,89,49));
console.log('passingAverage(33,61) returns: ' + passingAverage(33,61));
console.log("\n");
for console.log(passing average(75,42,98) and (34,93,77,89,49) indeed does return true which is correct. But, for the console log(33,61), when the 33+61/2 isn't clearly above 49, it returns true automatically for some reason when it should return false. What could be the reason?
That's because you're not passing an array as expected. passingAverage(33,61) pass two parameters.
If you want the function to have the same signature as you define it in the example you provided, then you should call it like this:
passingAverage([33,61]); // pass an array of elements
If you want to call the funtion like passingAverage(33,61) then the function should be defined like this:
function passingAverage(){ // no arguments, we will use the arguments array
var n = arguments; // arguments is defined for every function it's an array of all the arguments passed in
var average = 0, i;
for (i=0; i < n.length; i+= 1){
average += n[i];
}
if ((average/n.length)<49)
return false;
else
return true;
}
// then call the function like this
passingAverage(1, 65, 23, 22); // without using an array
This is a perfect example of why it's best to use debugger rather than console.logs to debug your code. Your function is always returning true because your average is always NaN:
function passingAverage(n) {
var average = 0, i;
for (i = 0; i < n.length; i += 1) {
average += n[i];
}
return average / n.length
}
console.log('passingAverage(75,42,98) returns: ' + passingAverage(75,42,98));
console.log('passingAverage(34,93,77,89,49) returns: ' + passingAverage(34,93,77,89,49));
console.log('passingAverage(33,61) returns: ' + passingAverage(33,61));
This is because you're passing two distinct float arguments to your method, which is in fact expecting an array of values:
function passingAverage(n) {
console.log("arguments:", n);
var average = 0, i;
for (i = 0; i < n.length; i += 1) {
average += n[i];
}
return average / n.length
}
passingAverage(75,42,98);
Simply pass your values as an array and you'll be good to go.
use arguments to loop over ALL function arguments regardless of length.
function passingAverage() {
var average = 0, i;
for (i = 0; i < arguments.length; i++) {
average += arguments[i];
}
if ((average/n.length)<49)
return false;
else
return true;
}

How do I finish this loop? Concatenate two previous characters

I'm making a function that when you give it a string, it will return the uppercase of the even numbered chars and the lower case of the odd numbered ones. So if you give it "HELLO" it will give you "HeLlO". This is obviously wrong since it only works for the first two characters. How do I complete the loop so that it doesn't keep concatenating the strings together?
function evenOddChange(source)
{
var i;
var result;
i = 0;
result = "";
while ( i < (source.length))
{
result = result + source.toUpperCase().charAt(i) + source.toLowerCase().charAt(i + 1);
i = i + 1;
}
return result;
}
You can usemodulo to check if its even or Odd.
function evenOddChange(source)
{
var i;
var result;
i = 0;
result = "";
while ( i < (source.length))
{
if(i%2==0){
result = result + source.toUpperCase().charAt(i);
}else{
result = result + source.toLowerCase().charAt(i);
}
i = i + 1;
}
return result;
}
Just use modulus to find if the index is odd or even and then use bracket notation.
function evenOddChange(source) {
var i = 0, result = "";
while (i < source.length)
result += source[i][i++ % 2 == 0 ? "toUpperCase" : "toLowerCase"]();
return result;
}
Note that when we are doing i++ % 2, the modulus operator operates on the value of i before we increment it. The increment effect will be felt only in the next iteration.
Increment by 2, not 1:
i = i + 2;
Not you are changing i and i+1, incrementing by only one will overwrite the i+1 change. This simple change will fix your problem.

capitalize the first letter of each word in a sentence

hey guy can anybody help me to fix my code so that it does the task shown in the text,
function tad(strg) {
var char = strg.split('-')
for (var i = 1; i < char.length; i++) {
return char[i].charAt(0).toUpperCase() + char[i].slice(1)
}
}
camelize("background-color") == 'backgroundColor'
camelize("list-style-image") == 'listStyleImage'
Assuming you want to replace all word combinations that have a hyphen in it to a camel cased word. You can use a regex with String.replace with a callback function that capitalizes all words after the hyphen.
function camelize (strg) {
return strg.replace(/-(\w)/g, function (match) {
return match[1].toUpperCase();
});
}
camelize("background-color");
// backgroundColor
camelize("z-index");
// zIndex
camelize("list-style-image");
// listStyleImage
JSFIDDLE
Change your function like bellow
function tad(strg) {
var char = strg.split('-')
for (var i = 1; i < char.length; i++) {
char[i] = char[i].charAt(0).toUpperCase() + char[i].slice(1)
}
return char.join('');
}
You are returning before the loop completes its iterations. The best thing here would be to use Array.prototype.reduce like this
function tad(strg) {
return strg.split('-').reduce(function(result, currentStr) {
return result + currentStr.charAt(0).toUpperCase() + currentStr.slice(1);
}, "");
}
console.log(tad("background-color") === "backgroundColor");
# true
console.log(tad("list-style-image") === "listStyleImage");
# true
First of all, you should concatenate results in some variable, instead of returning in loop.
Secondly fo not forget to add first element of array, since your loop is starting from 1.
function camelize(strg) {
var char = strg.split('-'), result = char[0]
for (var i = 1; i < char.length; i++) {
result += char[i].charAt(0).toUpperCase() + char[i].slice(1)
}
return result
}
alert(camelize("background-color"));
alert(camelize("list-style-image"));
Here is fiddle:
http://jsfiddle.net/C78T3/
You return from the whole function in the first iteration of that loop. Instead, you want to do that for every part, and the join the parts together:
function camelize(string) {
return string.split('-').map(function(part, i) {
return i ? part.charAt(0).toUpperCase() + part.slice(1) : part;
}).join("");
}
// or
function camelize(string) {
return string.split('-').reduce(function(m, part) {
return m + part.charAt(0).toUpperCase() + part.slice(1);
});
}
// or
function camelize(string) {
var parts = string.split('-'),
result = ""
for (var i = 1; i < parts.length; i++) {
result += parts[i].charAt(0).toUpperCase() + parts[i].slice(1)
}
return result;
}

count a how many times a letter appears in javascript using indexOf

I am trying to count how many times a letter appears in a string using indexOf(). Could you advise me on where I am going wrong in my code. Thanks!
var string = 'Lets find l as many times as we can. Love is natural, love you lots';
var myFunc = function (letter) {
newString = 0;
for (var i = 0; i < letter.length; i += 1) {
if (string.indexOf('l')) {
newString += 1;
}
}
return newString;
}
Instead of this
if (string.indexOf('l')) {
newString += 1;
}
You can use charAt or even direct indexing to check each letter of a string.
Like this
if (letter[i] == 'l') {
newString += 1;
}
or this
if (letter.charAt(i) == 'l') {
newString += 1;
}
Here's a FIDDLE
Note that if you were to use indexOf you'd want to call it directly on the string in question, like this
letter.indexOf('l')
The other answer is perfectly good, but in case you really want a solution using indexOf (as the title of your question suggests), you need to provide it a second parameter, to tell it where to start looking for the next occurrence:
var myFunc = function (str) {
var i = 0, c = 0;
do {
i = str.indexOf('l', i);
} while (++i && ++c);
return c;
}
Demonstration
But, if using indexOf is not a requirement, you can simplify this to:
var myFunc = function (str) {
return str.split('l').length - 1;
}
A recursive method if you are insistent upon indexOf:
var myFunc = function (str, letter) {
var count = 0,
p = str.indexOf(letter);
if (p > -1) {
count += (1 + myFunc(str.slice(p + 1, str.length - 1), letter));
}
return count;
};
Fiddle

Categories

Resources