This is a basic javascript question I just want to better understand. I'm trying to understand if it matters where I place my return true statement. Here's the example code:
function isValid(input) {
for (var i = 0; i < input.length - 2; i++) {
var charOne = input.charAt(i);
var charTwo = input.charAt(i + 1);
var charThree = input.charAt(i + 2);
if (charOne === charTwo && charOne === charThree) {
return false;
}
return true;
}
}
isValid("ABB");
This returns true, but also returns true if I place the return true statement here:
function isValid(input) {
for (var i = 0; i < input.length - 2; i++) {
var charOne = input.charAt(i);
var charTwo = input.charAt(i + 1);
var charThree = input.charAt(i + 2);
if (charOne === charTwo && charOne === charThree) {
return false;
}
}
return true; // Moved this return statement
}
isValid("ABB");
Is one way wrong and the other correct?
Your first version, you are returning true within the for loop. That means its only going to execute your loop once and then return. That's likely a bug.
Your second version is likely correct. The return true statement executes from the function after the for-loop completes all iterations from [i..length-2).
second one, since in the first one after each iteration , you check if characters are equal and it will return false or return true in the first iteration itself.In, second one you check for all combinations and if it's never false then it must be true.
When you return inside a for loop you finish the whole loop and carry on outside it.
So the answer is it depends, if you want to miss out an item and carry on looping after the return statement then doing a return isn't what you want.
The return you put outside of the loop allows the loop to complete before returning the result.
Note a useful keyword you can use inside a loop if you want to finish the iteration rather than breaking the whole loop is continue.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/continue
I don't think one is wrong necessarily. I actually prefer a slightly different approach.
For clarity I generally will do something like this. So it is clearly one or the other.
With a return it is obvious that calculations within the function stop at that point. I just like it to look obvious.
if(charOne === charTwo && charOne === charThree) {
return false;
} {
return true;
}
I've been trying to find out an efficient method of finding multiple numbers from an array that add up to a given number. In this instance I'm trying to find 3 numbers that total a target number.
I've got a basic working example below but unfortunately the recursive loop fails, it looks like there's an issue with it constantly looping. Ideally it would find the first possible answer and return it, but when it can't find an answer it gets stuck in the loop and breaks the browser.
Warning: the below code will break due to a memory leak:
let array = [5,6,3,3,6,67,2,2,6,7,7,2,1,3,4,5,67,7,4,2,5,6,3,3,6,67,2,2,6,7,7,2,1,3,4,5,67,7,4,2,5,6,3,3,6,67,2,2,6,7,7,2,1,3,4,5,67,7,4,2];
function findSums(arr, target, count) {
var result = [];
function recurse(start, leftOver, selection) {
if (leftOver < 0) return; // failure
if (leftOver === 0 && selection.length == count) {
result.push(selection); // add solution
return;
}
for (var i = start; i < arr.length; i++) {
recurse(i, leftOver-arr[i], selection.concat(arr[i]));
}
}
recurse(0, target, []);
return result;
}
// Demo
$('#input').on('blur', function(e){
let value = parseInt(e.target.value);
let result = findSums(array, value, 3);
if(result.length > 0){
$('#output').text(result[0]);
} else {
$('#output').text('Nothing found');
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>Input Number Below</h1>
<input id="input" type="number" />
<code id="output" ></code>
Well, it didn't break, when I tested, but still here are some tips:
You should set additional limitation to the count. You are making to much extra calls. When your function deals with really big sum, small numbers and small count it will call itself again until it reaches or overflows the desired sum, and only after that it will check current count. So you should add
if (selection.length > count) return;
Also. As I see there are many duplicates in your array, so I assume, that usage of the same number is allowed, but only if it is taken from another index. In your loop you are calling next recurse with the same start index. I think, you need
for (var i = start; i < arr.length; i++) {
recurse(i + 1, leftOver-arr[i], selection.concat(arr[i]));
}
And finally. This will not influence the recursive part of an algorithm, but maybe you'd like to filter out same results, or filter out your array to remove all duplicates.
Hope this helps.
Edit: sorry, missed the part about first possible solution. Here is the way to achieve this:
function recurse(start, leftOver, selection) {
if (leftOver < 0) return false; // failure
if (selection.length > count) return false;
if (leftOver === 0 && selection.length == count) {
result.push(selection); // add solution
return true;
}
for (var i = start; i < arr.length; i++) {
var res = recurse(i + 1, leftOver-arr[i], selection.concat(arr[i]));
if (res) return true;
}
}
I'm trying to do an indexof function. but we're not allowed to use it, or any build-in function in javascript. so i create my own. I upload it in our tester but there's only one condition that I didn't met. Thanks!
here's my code :
function indexofmyversion(searchChar,index) {
var a="";
for(var i=0; i<=searchChar.length; i++){
if(searchChar[i] == index){
return i;
}
} return -1; }
The test failed due to fact that the searching should start from index 4 , simply add another parameter as required
function indexofmyversion(searchChar,index, fromIndex) {
var a="";
for(var i=fromIndex; i<searchChar.length; i++){
if(searchChar[i] == index){
return i;
}
} return -1; }
This is my first question, so I apologize if this isn't formatted correctly or placed in the proper area.
I just completed the FreeCodeCamp checking for palindromes challenge. I can't help but think my solution was very inelegant.
function palindrome(str) {
var cleanString = str.replace(/[^A-Za-z0-9]/g, '');
var lowerCleanString = cleanString.toLowerCase();
var lowerArr = lowerCleanString.split('');
var reverseArr = lowerArr.reverse();
var joinedArr = reverseArr.join('');
if (joinedArr === lowerCleanString) {
return true;
}
// Good luck!
else {
return false;
}
}
I know it worked, but is it possible to do some of these steps together or in a cleaner way?
Simple function to check for palindromes
function checkPalindrome(palindrome) {
return palindrome == palindrome.split('').reverse().join('');
}
function palindrome(str) {
var newstr = str.replace(/[\W_]/g,'').toLowerCase();
if(newstr === newstr.split('').reverse().join('')){
return true;
}
return false;
}
palindrome("five|\_/|four");
You can use many methods in one row like I've used them .It's more simple :)
Good luck
Wow, I really like the answers comparing the string to a string.split('').reverse().join('') version of itself. I didn't think about that. Forgot about the .reverse() function. I ended up processing the string and splitting it out into an array and then using a double counter for the loop to compare the first and last items in the array. Was kinda fun to learn how to do that, but I like the .reverse() function use better.
In case someone is curious about the for loop I used ...
for(let i = 0, j = arr.length-1; i < j; i++, j--) {
if (arr[i] !== arr[j]) {
return false;
}
}
code:
method = function(a) {
//use associative array to keep track of the total number of appearances of a value
//in the array
var counts = [];
for(var i = 0; i <= a.length; i++) {
if(counts[a[i]] === undefined) {
//if the condition is looking for a[0],a[1],a[2],a[3],a[4],a[5] inside counts[] one value at a time and does not find them inside counts[] it will set each value to 1
counts[a[i]] = 1;
console.log(counts[a[i]]);
} else {
return true;
}
}
return false;
}
the js console logs 1x6
how can the condition see if a value inside counts[a[i]] has been repeated if all of the counts[a[i]] values are being set to 1 each iteration? wouldn't it always be comparing 1 to 1?
for example, if the a array is [1,2,3,4,5,2] and counts[a[1]](first int 2 in the array) is undefined and then set to 1, how would the condition know that counts[a[5]](second int 2 in the array) is the same value as counts[a[1]] and therefore it should return true?
perhaps I am misunderstanding whats going on.
I would appreciate any help. thanks
function counter(){
this.counts=[];
}
counter.prototype.add=function(a){
if(this.counts[a] === undefined) {
this.counts[a] = 1;
console.log(this.counts);
} else {
return true;
}
return false;
}
try this:
c= new counter();
c.counts;//[]
c.add(1);
c.counts;//[ ,1]
c.add(5);
c.counts;//[ ,1, , , ,1]
c.add(1);//true
...
may it helps you to understand whats going on