I have an exercise from my university that i have a string let's say i have that: "hello" and i want to print it like that:
hhehelhellhello (h he hel hell hello).
the thing that i stack is that they want to do it without loop!
Anyone can help me? :/
<!DOCTYPE html>
<html>
<body>
<h1>My First Web Page</h1>
<p>My first paragraph.</p>
<script>
var strin = "hello"
for (i = 0; i < strin.length; i++) {
document.write(strin.slice(0,i+1))
}
</script>
</body>
</html>
Use recursion. Code:
function r (s, i) {
if (i == undefined) i = 0;
if (i == s.length) return "";
return s.slice(0, i + 1) + r(s, i + 1);
}
r("hello"); // hhehelhellhello
There is probably a more efficient solution, but off the top of my head this should work:
var s = "hello";
var index = 0;
var len = 1;
var newString = '';
function appendToResult(str, index, len) {
newString += str.slice(index, len);
len++;
if (len !== s.length + 1) {
appendToResult(s, index, len);
}
}
appendToResult(s, index, len);
console.log(newString);
Maybe you can try a recursive approach:
function print(word, step){
if(word.length<step) return;
console.log(word.substring(1, step));
}
print('hello', 1);
Have you met.... Recursion?
What you need to achieve is something like this (for a string "hello"):
h
he
hel
hell
hello
A recursive call to a method (say, myPrinter()) could behave similarly:
call myPrinter(hello):
call myPrinter(hell):
call myPrinter(hel):
call myPrinter(he):
call myPrinter(h):
print 'h'
print 'he'
print 'hel'
print 'hell'
print 'hello'
done
So how do we go about writing this magical method of ours?
Take notice that at each call we make another call to our method but with a shorter input (in fact, the input has been truncated by one character from the end).
You could write something like this:
function myPrinter(myString):
myPrinter(myString - last character of myString);
print myString; // and maybe some space
if myString is empty:
return; // do nothing. just return
All that's left for you to do is translating the above idea into clean bug-free code.
Of course we have to loop this way or that way. Yet in the below code it is disguised as a recursive function. Yet i am using no counting variables at all. It has the potential to deceive inexperienced eyes. This is how i would do it;
function makeStringWeird(s){
var extend = (s, r=[]) => s !=="" ? (r.push(s),extend(s.slice(0,s.length-1),r)) : r;
return extend(s).reverse().join("");
}
console.log(makeStringWeird("hello"));
I landed up making two solutions for you. One is by using reduce function which doesn't explicitly uses any loop but when I checked its polyfill it uses a while loop to iterate. The code for that is given below and it can also be seen at this fiddle https://jsfiddle.net/vatsalpande/42590tre/
(function(){
var convertedString = [];
function reducer(previousValue, currentValue){
convertedString.push(previousValue+currentValue);
return previousValue+currentValue;
}
var string = "hello";
var stringArray = string.split("");
var totalVersion= stringArray.reduce(reducer,"");
console.info(convertedString.join(""));
})();
Since this was using iteration I created one more by using recursion alone. Below is the code and the fiddle link
https://jsfiddle.net/vatsalpande/tnxsuw75/
(function(){
var string = "hello";
var stringArray = string.split("");
var convertedValue = [];
function convert(initialValue, index){
if(index < stringArray.length){
convertedValue.push(initialValue+stringArray[index]);
convert(initialValue+stringArray[index], index+1);
}
}
convert("",0);
console.info(convertedValue.join(""));
})();
Hope these be of some help.
Any feedback to improve them is highly appreciated.
Happy Learning :)
Related
I was trying to use Heaps algorithm the opposite way by fixing elements at the beginning of array instead of last. But Im not able to get the results. Although I understood the theory part of this algorithm, it is confusing when I am trying to implement it. Im mainly confused about the swap statements inside the if condition. (please check comment). It would be helpful if someone can tell what the problem is. Thanks for your time.
function permute(string){
var str = string.split(""), strbrr = [];
function swap(strbrr,index1,index2) {
var temp = strbrr[index1];
strbrr[index1] = strbrr[index2];
strbrr[index2] = temp;
}
function permuteHelper(strarr, curr, end) {
if (curr == end)
console.log(strarr);
else{
var fixed = strarr[curr];
for(i=curr; i<=end; i++) {
permuteHelper(strarr,curr+1,end);
(end+1)%2 ? swap(strarr,end,curr) : swap(strarr,i,end); //This is the most confusing part for me. What is the code here?
}
}
}
permuteHelper(str,0,str.length-1);
}
var string1 = "ABCD";
permute(string1);
I'm trying to write a Javascript function that counts the vowels in a string by calling another function inside that function, but when I test it in the console it returns 0.
Here is my first function that works fine and recognizes if a string is a vowel:
function isVowel(ch){
var pattern = /[aeiouAEIOU]/
return pattern.test(ch);
};
For the second function none of my ideas have worked. Here are a few examples of what I have tried so far:
This one returns me a 0:
function countVowels(str){
var count = 0;
for(var i; i <= str.length; ++i){
if(isVowel(i)){
++count;
}
}
return count;
};
I also tried the above, but removing the .length after str in the for() area.
Another example, but this one gives me an error:
function countVowels(str){
var count = 0
var pattern = /[aeiouAEIOU]/
for(var i = 1; i <= str.length(pattern); ++i){
if(isVowel(i)){
++count;
}
}
return count;
};
I've tried various other functions as well, but for the sake of keeping this post relatively short I won't continue to post them. I'm quite new to Javascript and I'm not sure what I'm doing wrong. Any help would be greatly appreciated!
Try using .match() with the g attribute on your String.
g: global
i: case insensitive
Regexp documentation
function countVowels(ch){
return ch.match(/[aeiouy]/gi).length;
}
var str = "My string";
alert(countVowels(str)); // 2
Although Robiseb answer is the way to go, I want to let you know why you code is not working (I'm referring your first attempt). Basically you made two mistakes in the loop:
As CBroe stated, you are passing i to your isVowel function. i is a integer representing the index of the loop, not the actual character inside the string. To get the character you can do str.substr(i, 1), what means "give me one character from the position i inside the string".
You are not giving a initial value to the i variable. When you create a variable, it is undefined, so you can not increment it.
alert(countVowels("hello"));
function countVowels(str) {
var count = 0;
for (var i = 0; i <= str.length; ++i) {
if (isVowel(str.substr(i, 1))) {
count++;
}
}
return count;
};
function isVowel(ch) {
var pattern = /[aeiouAEIOU]/
return pattern.test(ch);
};
UPDATE: You will see that other answers use other methods to select the character inside the string from the index. You actually have a bunch of different options. Just for reference:
str.slice(i,i+1);
str.substring(i,i+1);
str.substr(i,1));
str.charAt(i);
str[i];
i is the index, not the character. It should be:
if (isVowel(str[i])) {
count++;
}
Also, str.length(pattern) is wrong. length is a property, not a function, so it should just be str.length.
You forgot to assign the value 0 to i variable
And parameter for isVowel is the character, not the index of string
Here information about the JS language: https://stackoverflow.com/tags/javascript/info
function isVowel(ch){
var pattern = /[aeiouAEIOU]/
return pattern.test(ch);
}
function countVowels(str){
var count = 0;
// you forgot to assign the value to i variable
for(var i = 0; i < str.length; i++){
// isVowel(str[i]), not isVowel(i)
if(isVowel(str[i])){
count++;
}
}
return count;
}
console.log(countVowels('forgot'))
Obviously you should do it this way:
function isVowel(c){
var lc = c.toLowerCase();
if(lc === 'y'){
return (Math.floor(Math.random() * 2) == 0);
}
return ['a','e','i','o','u'].indexOf(lc) > -1;
}
function countVowels(s){
var i = 0;
s.split('').each(function(c){
if(isVowel(c)){
i++;
}
});
return i;
}
console.log(countVowels("the quick brown fox jumps over the lazy dog"));
Which, although less efficient and less useful than other answers, at least has the entertaining property of returning a different count 50% of the time, because sometimes Y.
I have recently started learning coding and am trying to learn how to create functions but I am finding it quite difficult.
How would write a function called countDots(x) that takes a string as an argument and returns the number of dots (.) it contains.E.g. x = "www.google.com" the function will return with 2.
I would do it this way:
function dotCounter(x) {
return x.split('.').length -1;
}
document.write( dotCounter("www.google.com") );
Please try this
function countDots(x){
return((x.match(/\./g) || []).length)
}
As you say you're learning to code at the moment, you don't need speed-optimised code. I'd suggest this - it only use ideas that turn up in almost all programming languages:
function countDots(str) {
var count = 0;
for (var x = 0; x < str.length; x++) {
if str.charAt(x) == '.' {
count++;
}
}
return count;
}
You can worry about speed once you're happy that you've got the basics! Good luck
I got used to using bind to remember the last result of function and to keep track to be able to use the last result for the next result. For instance to concat or join last string to a new string without using outer variables:
function remStr(outStr){
return function c(lastStr,newStr){
if(!newStr)return lastStr;
var all = lastStr+newStr;
return c.bind(null,all);
}.bind(null,outStr);
}
var str = remStr('stack');
str = str('over');
str = str('flow');
str(); // stackoverflow
The problem is that I want to call remStr several times and so bind came into play. But can it be done better or just differently, maybe it turns out that for one case an approach fulfills a task better than remStr?
If I understand your intention correctly, how about just using the closure?
function remStr(outStr) {
return function c(newStr) {
if (!newStr) return outStr;
outStr += newStr;
return c;
}
}
var str = remStr('stack');
str = str('over');
str = str('flow');
str(); // stackoverflow
As mentioned by Tomalak in the comments, JavaScript strings are immutable, so if you intend to use large or many strings, you will probably want to buffer them in an array.
function remStr(outStr) {
var buffer = [outStr || ''];
return function c(newStr) {
if (!newStr) return buffer.join('');
buffer.push(newStr);
return c;
}
}
var str = remStr('stack');
str = str('over');
str = str('flow');
str(); // stackoverflow
You shouldn't be using Function.bind here at all. You can cache the arguments. And then join it.
This approach is widely known as functions are also objects and can have properties. Function.bind is used to change the context of the given function and that isn't what we want.
function concat(word){
return function fn(anWord){
if(!anWord) return fn.words.join("");
(fn.words || (fn.words = [word])).push(anWord);
}
}
Now you can use it like below:
var str = concat("stack");
str("over");
str("flow");
console.log(str()); // "stackoverflow"
There's a gap in my JavaScript knowledge here. I want to search an array of objects values for a particular value and return it.
For the year I have been writing JavaScript, I have been implementing it like this:
var itemClicked = (function(){
var retval;
//Note self.inventory.itemsArray is an array of JS objects
$(self.inventory.itemsArray).each(function(i){
if(parseInt(this.id) === parseInt(idOfItem)){
retval = this;
return false;
}
});
return retval;
})();
It works, but I'm sure as anything there is a more elegant way. Tell me please!
EDIT - Solution
Thanks to #gdoron with his answer below.
var myVar = $(self.owner.itemsArray).filter(function(){
return parseInt(this.id) == parseInt(recItemID);
}).get(0);
Note: .get(0) was added at the end because myVar is wrapped as a jQuery object.
The native jQuery function for this is filter:
$(data).filter(function(){
return this.id == "foo";
});
It's shorter than code you have and more important a lot more readable.
About efficiency, it will iterate all the elements in the set to find as much as possible matches, but I hardly believe it will be the bottle neck of your application, don't focus on micro-optimisations.
I suggest you read Eric Lipper blog about Which is faster.
You can also use grep as suggested by #Mattias Buelens:
$.grep(data, function(ele){
retun ele.id == "foo";
});
Just another option using jQuery's $.grep( ) function
var arr = $.grep( self.inventory.itemsArray, function ( n ) {
return n.id == idOfItem;
});
The above returns an array of matching array elements. If you just want the first it is easy enough to return arr[0] if it exists.
Although I'm unsure what the function is actually supposed to do (due to the external contexts' variables), the following should be more efficient cycle-wise
var itemClicked = (function(){
var i, array = self.inventory.itemsArray, length = array.length;
for( i=0; i < length; i++) {
if(parseInt(array[i].id) === parseInt(idOfItem)){
return array[i];
}
}
return undefined;
})();
It's an array of Javascript objects
Then do not use jQuery at all. At least, use $.each instead of building a wrapper object around the array. Still, a simple for-loop is much shorter and more performant:
var itemClicked = (function(idnum) {
var arr = self.inventory.itemsArray;
for (var i=0, l=arr.length; i<l; i++)
if (parseInt(arr[i].id, 10) === idnum)
return arr[i];
})( parseInt(idOfItem, 10) );
You might as well think of storing the id properties as numbers right away, so you don't need to convert it each time.