I have 2 functions on a single .js file.
function notUsed(id) {
//default to false because if true then id not being used and good for new user
var notInUse = false;
console.log(notInUse);
return !notInUse;
}
function generateID() {
//number of zeros represents the number of digits in id code
const SIZEOFID = 10000000;
const ID_DIGITS = 7;
//letter to start id for non los rios people
const STRTOFID = "C";
//variable to hold finished id code & variable to hold 7 digit of id code
var id, idNum;
//loop to make sure id contains 7 digits and 1 letter and not used already
do {
idNum = Math.round(Math.random() * SIZEOFID);
idNum.toString();
id = (STRTOFID + idNum);
}while(id.length != (ID_DIGITS+1) && notUsed(id));
console.log(id);
}
When I call generateID() from my web page, the ID gets logged but false does not get logged(Obviously notUsed function is incomplete). However, if I call each function separately from my web page, both the ID and false get logged. How can I fix or work around this issue? Any comments help.
The logical and is short-circuiting because the first comparison is false. The second never gets evaluated, which is why it's not logging. It's not being called.
It`s happened because first condition in while id.length != (ID_DIGITS+1) return false, if first condition return false next conditions will not be called
Example:
function imreturnTrue() {
console.log('imreturnTrue');
return true
};
function impreturnFalse() {
console.log('impreturnFalse');
return false
};
function imreturnTrue1() {
console.log('imreturnTrue1');
return true
};
let example = imreturnTrue() && impreturnFalse() && imreturnTrue1();
// imreturnTrue impreturnFalse
let example1 = imreturnTrue() && imreturnTrue1() && impreturnFalse() ;
// imreturnTrue imreturnTrue1 impreturnFalse
let example2 = impreturnFalse() && imreturnTrue() && imreturnTrue1() ;
// impreturnFalse
Related
I have a task and I need a function that validate '123456' equals '213456','312456' etc. Maybe, I missing something, but absolutely have no idea how to validate it
I tried to do regexp like if(userInput = [/answer/g] return true but it isn't work
The following checks that one string is a permutation of another as long as all the characters in the set string are different.
let s = new Set('123456');
let input = '213456';
if(input.length === s.size && [...input].every(c => s.has(c)))
return true;
let string = '123457';
let user_input ='623451';
function compare(string, user_input)
{
if(string.length == user_input.length)
{
for (let i = 0; i < string.length; i++) {
if (user_input.includes(string[i])) continue;
else
return false;
}
return true;
}
else
{
console.log('failure');
}
}
console.log(compare(string, user_input));
you might like this solution
Here a solution which runs in O(n) and can also be used if the expected string contains duplicate charaters like e.g. 112233 (see second example within the code), which other solutions posted here are not taking into consideration.
The idea here is that you first create a lookup table (I am using a JavaScript object here) once which holds all the numbers/ characters and their count within the expected word. Then using this lookup table I check for any of the characters in a user supplied word (the word which has to be validated) if it has all the expected characters and (this is the distinction to other answers posted here) if their count matches the expected count of said character/ number. If one string is a permutation of the other the lookup table should have 0 as the count for every single character. If any character is not 0, it is not a permutation.
function validate(userInput, validOptionsMap) {
// create a copy as we are mutating the values within the object
const validOptionsWithCount = { ...validOptionsMap
};
const elementsMatch = userInput.split("").every(input => {
if (validOptionsWithCount[input]) {
const count = validOptionsWithCount[input];
if (count === 0) {
return false;
}
validOptionsWithCount[input] = count - 1;
return true;
}
return false;
});
if (!elementsMatch) return false;
return Object.values(validOptionsWithCount).every(count => count === 0);
};
function buildLookupTableForExpectedPermutation(expectedPalindrome) {
return expectedPalindrome.split("")
.reduce((all, cur) => (all[cur] ?
all[cur] = all[cur] + 1 :
all[cur] = 1, all), {});
}
// Your example
const permutation = "123456";
const validOptionsWithCount = buildLookupTableForExpectedPermutation(permutation);
console.log(`Checking for permutations of ${permutation}`)
console.log("123456:", validate("123456", validOptionsWithCount)); // true
console.log("123457:", validate("123457", validOptionsWithCount)); // false
console.log("265413:", validate("265413", validOptionsWithCount)); // true
console.log("2654131:", validate("2654131", validOptionsWithCount)); // false
console.log("261413:", validate("261413", validOptionsWithCount)); // false
// example with multiple identical values (other solutions posted here will fail at least one of these tests)
const permutation2 = "112233";
const validOptionsWithCount2 = buildLookupTableForExpectedPermutation(permutation2);
console.log(`Checking for permutations of ${permutation2}`)
console.log("112233:", validate("112233", validOptionsWithCount2)); // true
console.log("123123:", validate("123123", validOptionsWithCount2)); // true
console.log("123131:", validate("123131", validOptionsWithCount2)); // false
console.log("1231231:", validate("1231231", validOptionsWithCount2)); // false
console.log("12312:", validate("12312", validOptionsWithCount2)); // false
Trying to optimise pattern matching code. Old code has few patterns which were matched against an Id coming from the callback data.
var Id = callbackData.Id
var pattern1 = /gen/g;
var pattern2 = /0--google/g;
var pattern3 = /mail/g;
var isPattern1 = pattern1.test(Id)
var isPattern2 = pattern2.test(Id)
var isPattern3 = pattern3.test(Id)
if(Id && Id !== 0 && !isPattern1 && !isPattern2 && !isPattern3)
{
//return statement
// function
} else {
//return statement
//function
}
To optimise it I have created a json file which consists the patterns. Pattern are being read from the json file and matched with the Id.
Json file : test.json
{
"PatternToSearch": {
"pattern1" : "gen",
"pattern2" : "^0--google",
"pattern3" : "mail"
}
}
var patternToMatch = require('test.json');
var patternArray = [];
Object.keys(patternToMatch.PatternToSearch).forEach(function (key) {
var value = PatternToMatch.PatternToSearch[key];
patternArray.push(value);
});
return Promise.all(patternArray);
.then(patternArrayResult => {
for (var val in patternArrayResult) {
var pattern = patternArrayResult[val];
var patternToCompare = new RegExp(pattern);
var isPattern = patternToCompare.test(Id);
}
})
I tried forEach as well but I am returning boolean value from the function and forEach doesn't return any value so I used for...in
not able to replicate this condition Id && Id !== 0 && !isPattern1 && !isPattern2 && !isPattern3. How to do it?
Tried
if(isPattern){
if(Id && Id !==0 && isPattern) {
// return statement
}
}
but this condition doesn't work when all the patterns don't match with Id. As I am this inside for loop only once this
condition will be true and other times false which takes the controller in else loop
How to replicate the condition? (Id && Id !== 0 && !isPattern1 && !isPattern2 && !isPattern3)
This is a job for some, which returns true if any item in an array causes a given function to return a truthy value:
return patternArray.some(v=>RegExp(v).test(Id));
And to include the value of Id in the test as well:
return Id && patternArray.some(v=>RegExp(v).test(Id));
You don't need to separately test Id !== 0 because a zero value will already be treated as falsy value, causing the && to short-circuit early. (So, Id && Id !== 0 will only ever produce 0 or true: execution flow cannot ever reach the condition Id !== 0 when that condition would be false, because the test Id for a zero value would have already terminated the && flow early.)
I am trying to write some logic that will check for the existence of a specific record in two tables.
If the row exists in either table, I want to return TRUE.
For table A, when the record is added to the table, the id field looks like "123".
For table B, the same record would have the id of "a123". However, the value i have to search for the record is "row_123".
This is what my code looks like right now :
var checkForDuplicates = function(row_id) {
return !!($('#existing_members').find('#' + row_id.replace('row_','')).length || $('#selected_users').find('#' + row_id.replace('row_','a').length) );
};
I want the function to return true if the record exists in either table.
However, this statement returns true in cases when it should be false.
What I've tried so Far
I've been playing around in the console to make sure that my logic is correct:
!!(1 || 0) //returns true
!!(0 || 0) //returns false
!!(0 || 1) //returns true
I'm also currently reviewing the replace statements to make sure the find() is being supplied the right strings.
But a second pair of eyes to confirm that my logic is correct would be appreciated.
Thanks
EDIT 1
The solution, using Max's suggestion would be:
var checkForDuplicates = function(row_id) {
var parts = row_id.split('_');
var tableB = '#a'+ parts[1];
var tableA = '#' + parts[1];
return !!($('#existing_members').find(tableA).length || $('#selected_users').find(tableB).length);
}
However, as Ankit points out, I just had a typo in my original code. So this would be my final answer / solution:
var checkForDuplicates(row_id) {
return !!( $('#existing_members').find('#' + row_id.replace('row_', '')).length || $('#selected_users').find('#' + row_id.replace('row_','a')).length);
}
Your code has a typo at the end of return statement
...'a').length)); //it returns object which always evaluates to true
it should be
...'a')).length);
DEMO
var checkforduplicates = function(row_id){
//row_id looks like "row_123"
return !!($('#tableA').find('#' + row_id.replace('row_','')).length || $('#tableB').find('#' + row_id.replace('row_','a')).length );
}
alert(checkforduplicates("row_123"));
<table id=tableA><tr><td id="123">123 ID</td></tr></table>
<table id=tableA><tr><td id="a13">a13 ID</td></tr></table>
Corrected few issues to make the code more efficient:
var checkforduplicates = function(row_id) {
var id = row_id.split('_')[1]; // [ 'row', '123']
return $('#'+id).length || $('#a'+id).length;
}
No need for !! as operator || produces boolean result (true or
false)
Used $('#'+id) as more efficient jQuery selector
Removed unnecessary find(..) call
Eliminated unnecessary parenthesis (which had an issue)
I want the function to return true if the record exists in either table.
var checkForDuplicates = function(row_id) {
row_id = row_id.substring(4); // 'row_123' -> '123'
var table_A_row_id = row_id;
var table_A_row_exists = $('#tableA').find('#' + table_A_row_id).length > 0;
var table_B_row_id = 'a' + row_id;
var table_B_row_exists = $('#tableB').find('#' + table_B_row_id).length > 0;
return table_A_row_exists || table_B_row_exists;
};
of course it is returning the opposite of the things you want, cause you are using !!.
! is used to negotiate the return value of the specific function/variable e.g.:
if(!var_x == false)
this example only works if var_x is true.
So please be aware to avoid !! ;)
Please use a single ! instead!
I want to have an array with values, one 'true' for each object in my model.
As you can see in my JSFiddle - Hardcoded working, I have currently hard coded the values, and then it works, i.e. the "level 2" tables being collapsed from start.
$scope.dayDataCollapse = [true, true, true, true, true, true];
$scope.dayDataCollapseFn = function () {
for (var i = 0; $scope.storeDataModel.storedata.length - 1; i += 1) {
$scope.dayDataCollapse.append('true');
}
};
But when I replace the hardcoded with an empty array and a function (shown above) to populate it for me, meaning appending 'true' for each store in the storeDataModel, it fails. All level 2 tables are expanded from start, but can collapse them by clicking two times (one for adding value to array and one for collapsing).
Have also tried with a "real" function...:
function dayDataCollapseFn() {
for (var i = 0; $scope.storeDataModel.storedata.length - 1; i += 1) {
$scope.dayDataCollapse.append('true');
}
};
...but I can't get the $scope.dayDataCollapse to populate initally.
How can I solve this?
Your for loop is incorrect. The middle expression is evaluated for true/false, but you've just coded it to be a constant value (well, constant for any invocation of the function anyway). Try this:
function dayDataCollapseFn() {
for (var i = 0; i < $scope.storeDataModel.storedata.length; i += 1) {
$scope.dayDataCollapse.push(true);
}
};
Your function would have done nothing at all if the model had one element, and locked up the browser with a "slow script" warning if the model had zero or more than one elements.
Also note that you should use true, the boolean constant, and not the string 'true'.
edit — also note that it's .push(), not .append()
#Pointy got me in right direction...thanks! =)
...and then I solved the last thing.
I forgot that I had used a negation, i.e. data-ng-show="!dayDataCollapse[$index]" since I was using collapse="dayDataCollapse[$index]" first. Then I removed the collapse since it didn't work well together.
Anyhow...since I removed the bang (!) I could also use false instead of true and then of course switch the booleans in the $scope.selectTableRow() function as well.
The last thing was that I had if-else, where the if statement checked if dayDataCollapse was undefined and then an else for the logic. Of course the logic did not trigger first time as it was undefined.
Functions that made it work...:
$scope.dayDataCollapseFn = function () {
$scope.dayDataCollapse = [];
for (var i = 0; i < $scope.storeDataModel.storedata.length; i += 1) {
$scope.dayDataCollapse.push(false);
}
};
$scope.selectTableRow = function (index, storeId) {
if ($scope.dayDataCollapse === undefined) {
$scope.dayDataCollapseFn();
}
if ($scope.tableRowExpanded === false && $scope.tableRowIndexCurrExpanded === "" && $scope.storeIdExpanded === "") {
$scope.tableRowIndexPrevExpanded = "";
$scope.tableRowExpanded = true;
$scope.tableRowIndexCurrExpanded = index;
$scope.storeIdExpanded = storeId;
$scope.dayDataCollapse[index] = true;
} else if ($scope.tableRowExpanded === true) {
if ($scope.tableRowIndexCurrExpanded === index && $scope.storeIdExpanded === storeId) {
$scope.tableRowExpanded = false;
$scope.tableRowIndexCurrExpanded = "";
$scope.storeIdExpanded = "";
$scope.dayDataCollapse[index] = false;
} else {
$scope.tableRowIndexPrevExpanded = $scope.tableRowIndexCurrExpanded;
$scope.tableRowIndexCurrExpanded = index;
$scope.storeIdExpanded = storeId;
$scope.dayDataCollapse[$scope.tableRowIndexPrevExpanded] = false;
$scope.dayDataCollapse[$scope.tableRowIndexCurrExpanded] = true;
}
}
Updated JSFiddle
function checkData() {
var temp = 0;
var totalMarks = countMark(temp);
if (totalMarks != 100)
window.alert("Marks must total 100");
}
function countMark(mark) {
var totalMark = 0;
totalMark += parseInt(mark)
return totalMark;
}
function doAdd() {
var taskid = document.getElementById("taskid").value;
var taskname = document.getElementById("taskname").value;
var taskmark = document.getElementById("taskmark").value;
if (taskid.length === 0)
window.alert("Task Id cannot be empty!");
if (taskname.length === 0)
window.alert("Task name cannot be empty!");
if (taskmark.length === 0)
window.alert("Task Mark cannot be empty!");
else if (!markpattern.test(taskmark))
window.alert("Invalid data in mark field");
var marks = parseInt(document.getElementById("taskmark"));
if (marks < 0 || marks > 100)
window.alert("Marks out of range. Please re-enter");
countMark(marks);
}
My question is when i keep call the doAdd() function. my marks will keep adding . want to do like passing reference like in C++ . my function countMark(...) will keep adding .
after that, when my form submitted, my form will call the function checkData()
If my totalmark is not 100 . will prompt out the alert and error.
but my code is not working . I guess that my countMark function wrong somewhere
If I understand you correctly, you're looking for the equivalent of a static variable - something that gets initialized the first time the function is called, and keeps it's value for subsequent calls.
Take a look at this related question: https://stackoverflow.com/a/1535650/2444111
The top answer (by CMS) is talking about class-based static variables, which are not quite the same thing.
The second answer (by Pascal MARTIN) is what you're looking for. It takes advantage of the fact that JS functions are also objects, and stores the variable as a property of the function object. This is a better solution than using a global variable (or a property of window, which is what a global actually is)
There are several issues in your code and it's really hard to say what your intention was. But I will address what I found.
In the following piece of code you are requesting a DOM Element and try to parse it as an Integer. The result of that type convertion is always NaN. Maybe wanted to get the value attribute of your element, like you did before. (Also, don't request the same element multiple times. Request it once, save the result in a variable and use that variable from that on).
var marks = parseInt(document.getElementById("taskmark"));
if (marks < 0 || marks > 100)
window.alert("Marks out of range. Please re-enter");
countMark(marks);
Your function countMark is pretty useless, because it will always return whatever Number you pass to it (see comments in your code).
function countMark(mark) {
var totalMark = 0; //create a new variable with value 0
totalMark += parseInt(mark) //add "mark" to that variable
return totalMark; //return that variable => 0 + mark = mark (and if mark = NaN => 0 + mark = NaN)
}
Maybe you wanted to make totalMark a global variable, than you would need to define it outside of your function:
var totalMark = 0;
function countMark(mark) {
totalMark += parseInt(mark);
return totalMark;
}
Last but not least, lets analyse your function checkData:
function checkData() {
var temp = 0; //create a local variable with value 0
var totalMarks = countMark(temp); //pass 0 to countMark => return 0 => totalMarks = 0
if (totalMarks != 100) //always true since totalMarks is always 0
window.alert("Marks must total 100"); //will always alert
}