How do I check if an input contains an isbn using javascript - javascript

I need a script that will test an input field's contents to see if it contains an ISBN. I found a few examples of this, but none of them strip the dashes. I need this to happen or my search results don't work. I have the else part of the script working if the field doesn't have an ISBN, but can't get the ISBN test to work. Thank you in advance for any help!
function search() {
var textboxdata = $('#search').val();
if (textboxdata contains an ISBN number, strip it of dashes and) {
// perform ISBN search
document.location.href = "http://myurl?search=" + textboxdata;
}
else { //perform other search
}
}

Based on the algorithms given in the Wikipedia article, here's a simple javascript function for validating 10- and 13-digit ISBNs:
var isValidIsbn = function(str) {
var sum,
weight,
digit,
check,
i;
str = str.replace(/[^0-9X]/gi, '');
if (str.length != 10 && str.length != 13) {
return false;
}
if (str.length == 13) {
sum = 0;
for (i = 0; i < 12; i++) {
digit = parseInt(str[i]);
if (i % 2 == 1) {
sum += 3*digit;
} else {
sum += digit;
}
}
check = (10 - (sum % 10)) % 10;
return (check == str[str.length-1]);
}
if (str.length == 10) {
weight = 10;
sum = 0;
for (i = 0; i < 9; i++) {
digit = parseInt(str[i]);
sum += weight*digit;
weight--;
}
check = (11 - (sum % 11)) % 11
if (check == 10) {
check = 'X';
}
return (check == str[str.length-1].toUpperCase());
}
}

There is also a js library available for checking ISBN10 and ISBN13 formatting: isbnjs as well as isbn-verify
Edit 2/2/17 - previous link was to Google Code, some updated current links:
- npm for isbn-verify
- npm for isbnjs
- Github project

Take a look at this Wikipedia article:
http://en.wikipedia.org/wiki/International_Standard_Book_Number
Should give you some insight into how to validate an ISBN number.

Derek's code fails for this ISBN ==> "0756603390"
It's because the check digit will end up as 11.
incorrect == > check = 11 - (sum % 11);
correct ==> check = (11 - (sum % 11)) %11;
I tested the new code against 500 ISBN10s.

Related

I have made a simple calculator but How I can prevent users from entering dot several times in one number ? so far i can only prevent double dots

if
(previousNum == "." && currentNum == ".") {
screen.value = screen.value.substring(0, numchar - 1);
You are using javascript. you can split it on "." then count the length of the array which should be 2 or less.
var x = '12.34.56';
var arr = x.split(".")
var number_of_dots = arr.length - 1
console.log(number_of_dots)
I think you can check if the number is Integer or float with this sample function
function isFloat(n){
return Number(n) === n && n % 1 !== 0;
}
function isInt(n) {
return n % 1 === 0;
}
and write catch, so if had error the entered number is not valid for you calculator

LeetCode 125: Palindrome Number Easy Leetcode [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
This is my answer. However, I couldn't pass the test case for "11".
I couldn't find what is wrong in the code. Please help! Thank you!
/**
* #param {number} x
* #return {boolean}
*/
var isPalindrome = function(x) {
if (x === 0) {
return true;
}
if (x < 0 || x % 10 === 0) {
return false;
}
let rev = 0;
while (x > rev) {
pop = x % 10;
x = x / 10;
rev = (rev * 10) + pop;
}
if (x === rev || x === rev / 10) {
return true;
}
else {
return false;
}
};
Finding palindromes is inherently something which you would typically do using strings, not numeric variables, so I suggest converting your number to a string, and going from there:
var isPalindrome = function(x) {
x = x + ""; // convert to string, if x be a number
var isPalindrome = true;
for (i = 0; i < x.length/2; i++) {
if (x.substring(i, i+1) != x.substring(x.length-1-i, x.length-i)) {
isPalindrome = false;
break;
}
}
return isPalindrome;
}
console.log(isPalindrome(1234321));
console.log(isPalindrome(1234329));
The strategy here is just to iterate half the string, and assert that each character matches its counterpart in the other half. Note that we don't need to check the middle character, in the case of an input with an odd number of characters.
Your question seems to be LeetCode 9 and in the discussion board, there are good accepted solutions such as:
JavaScript
var isPalindrome = function(x) {
if (x < 0)
return false;
let reversed = 0;
for (let i = x; i > 0; i = Math.floor(i / 10))
reversed = reversed * 10 + i % 10;
return reversed === x;
};
Python
class Solution:
def isPalindrome(self, x):
if x < 0 or (x > 0 and not x % 10):
return False
return str(x) == str(x)[::-1]
Java
class Solution {
public boolean isPalindrome(int x) {
if (x < 0 || (x != 0 && x % 10 == 0))
return false;
int reversed = 0;
while (x > reversed) {
reversed = reversed * 10 + x % 10;
x /= 10;
}
return (x == reversed || x == reversed / 10);
}
}
There is another similar isPalindrome question that if you might be interested, I've just copied below:
JavaScript I
var isPalindrome = function(s) {
var original = s.replace(/\W/g, ''); // means NON-WORD characters
var reversed = original.split('').reverse().join('');
return original.toLowerCase() == reversed.toLowerCase();
};
JavaScript II
var isPalindrome = function(s) {
var original = s.replace(/[^a-z0-9]/isg, '');
var reversed = original.split('').reverse().join('');
return original.toLowerCase() == reversed.toLowerCase();
};
Java
class Solution {
public boolean isPalindrome(String s) {
String original = s.replaceAll("(?i)[^a-z0-9]", "").toLowerCase();
String reversed = new StringBuffer(original).reverse().toString();
return original.equals(reversed);
}
}
Python
class Solution:
def isPalindrome(self, s):
s = ''.join(re.findall(r'(?is)[a-z0-9]+', s)).lower()
return s == s[::-1]
\W (non-word-character) matches any single character that doesn't match by \w (same as [^a-zA-Z0-9_]).
Reference
You can find additional explanations in the following links:
LeetCode 9 JavaScript Discussion Board
LeetCode 125 JavaScript Discussion Board
Using string for checking palindrome is very easy and straight forward. Having said that if you want to see how you can do it without changing number to string,
First initialise an variable start with Math.pow(10, digit count-1)
Loop till the value of start is greater than 0
inside loop compare the first and last digit if they are not equal return false
on each iteration remove the first and last digit from x and reduce start by 100
var isPalindrome = function(x) {
// as per question on leetcode negative values cannot be palindrome
if( x < 0) {
return false
}
x = Math.abs(x)
// to get the digits from start we need to get log10 of given value
let len = Math.ceil( Math.max( Math.log10(x), 1 ) ) - 1
let start = Math.pow(10, len)
while(start){
// compare first digit with the last digit
if(Math.floor(x/start) != (x % 10)){
return false
}
// remove first digit of current x
x = x % start
// remove last digit of current x
x = Math.floor(x/10)
// reduce start by 100 as we removed 2 digits
start = Math.floor(start / 100)
}
return true
};
console.log(isPalindrome(1))
console.log(isPalindrome(1221))
console.log(isPalindrome(-121))
console.log(isPalindrome(12341))
console.log(isPalindrome(100111))
Note:- We do (digit count - 1) so that we can capture the first digit
Original leetcode question link

Optimizing and finding edge cases that I might have missed - 2 coding interview questions

Background - I took an online coding test and was presented with questions similar to this, I did rather poorly on it compared to the hidden grading criteria and I was hoping to get another pair of eyes to look at it and maybe help point out some of my mistakes.
Practice Test questions -
Task: Given an integer inject the number 5 into it to make the largest possible integer
Conditions: (-80000...80000) range needed to handle
Expected input: int
Expected output: int
Testcase: -999 -> -5999
80 -> 850
var lrgInt = function(num) {
var stringInt = num.toString();
for (let i = 0; i < stringInt.length; i++) {
if (stringInt.charAt(i) === "-") {
return parseInt([stringInt.slice(0, 1), '5', stringInt.slice(1)].join(''));
}else if (stringInt.charAt(i) < 5) {
return parseInt([stringInt.slice(0, i), '5', stringInt.slice(i)].join(''));
}
}
return parseInt([stringInt.slice(0, stringInt.length), '5', stringInt.slice(stringInt.length)].join(''));
};
Task: Determine the number of operations done on a number following the conditions to reduce it to 0.
Conditions:
- If the number is odd, subtract 1
- If the number is even, divide by 2
Expected input: int
Expected output: int
var operations = 0;
var numberOfSteps = function(num) {
if (num === 0){
return operations;
}else if (num % 2 == 0) {
operations++;
return numberOfSteps(num/2);
} else {
operations++;
return numberOfSteps(num-1);
}
};
For the second question, you could add one plus the result of recursion with the adjusted number without having a global counter.
function numberOfSteps(number) {
if (!number) return 0;
if (number % 2) return 1 + numberOfSteps(number - 1);
return 1 + numberOfSteps(number / 2);
}
console.log(numberOfSteps(5)); // 5 4 2 1 0
For the first question, we make the observation that if the number is positive, we want to inject the 5 before the first digit less than 5, but if it's negative then we want to inject it before the first digit greater than 5. For the second problem, we can just use a simple while loop.
function largestNum(num) {
if (num == 0) {
// this edge case is weird but I'm assuming this is what they want
return 50;
}
var negative = num < 0;
var numAsStr = Math.abs(num).toString();
var inj = -1;
for (var i = 0; i < numAsStr.length; i++) {
var cur = parseInt(numAsStr[i], 10);
if ((!negative && cur < 5) || (negative && cur > 5)) {
// we found a place to inject, break
inj = i;
break;
}
}
if (inj == -1) {
// didn't inject anywhere so inject at the end
inj = numAsStr.length;
}
return (
(negative ? -1 : 1) *
parseInt(numAsStr.substr(0, inj) + "5" + numAsStr.substr(inj))
);
}
function numSteps(num) {
var steps = 0;
while (num != 0) {
if (num % 2) {
// it's odd
num--;
} else {
num /= 2;
}
steps++;
}
return steps;
}

Determining prime numbers

I'm trying to write a function that determines whether a value is a prime number and then displays a message to provide the outcome. Unfortunately, it doesn't work - no error messages displayed, and I can't see a logical reason why. ( For info, it calls a function numbers() which I have tested independently and it works - it provides a single positive integer). I'm not very experienced in javascript, but have developed the below from learning online. Any pointers in the right direction would be very much appreciated.
function validate() {
var message = "This number is ";
var number;
var value = numbers();
var indicator = true;
for (int i=2; i <= value/2; i++) {
number = value % i;
if (number==0) {
indicator = false;
//or indicator = number % 2 != 0;
break;
}
}
if (indicator) {
message += "a prime number.";
}
else {
message += "not a prime number.";
}
document.getElementById('text').innerHTML = message;
}
Only even number that is prime is 2, so discard all the others that is divisible by 2
Minimize the iteration by considering odds only
Minimize a bit more by iterating to root of given number
So what you can do is write a method like the following:
function isPrime(number) {
if (number === 2) return true;
if (number % 2 === 0) return false;
var flag = true;
var i, length = Math.ceil(Math.sqrt(number));
for (i = 3; i <= length; i += 2) {
if (number % i === 0) {
flag = false;
break;
}
}
return flag;
}
replace int to var in for loop
for (var i=2; i <= value/2; i++) {

Count bytes in textarea using javascript

I need to count how long in bytes a textarea is when UTF8 encoded using javascript. Any idea how I would do this?
thanks!
encodeURIComponent(text).replace(/%[A-F\d]{2}/g, 'U').length
Combining various answers, the following method should be fast and accurate, and avoids issues with invalid surrogate pairs that can cause errors in encodeURIComponent():
function getUTF8Length(s) {
var len = 0;
for (var i = 0; i < s.length; i++) {
var code = s.charCodeAt(i);
if (code <= 0x7f) {
len += 1;
} else if (code <= 0x7ff) {
len += 2;
} else if (code >= 0xd800 && code <= 0xdfff) {
// Surrogate pair: These take 4 bytes in UTF-8 and 2 chars in UCS-2
// (Assume next char is the other [valid] half and just skip it)
len += 4; i++;
} else if (code < 0xffff) {
len += 3;
} else {
len += 4;
}
}
return len;
}
[June 2020: The previous answer has been replaced due to it returning incorrect results].
Most modern JS environments (browsers and Node) now support the TextEncoder API, which may be used as follows to count UTF8 bytes:
const textEncoder = new TextEncoder();
textEncoder.encode('⤀⦀⨀').length; // => 9
This is not quite as fast as the getUTF8Length() function mentioned in other answers, below, but should suffice for all but the most demanding use cases. Moreover, it has the benefit of leveraging a standard API that is well-tested, well-maintained, and portable.
If you have non-bmp characters in your string, it's a little more complicated...
Because javascript does UTF-16 encode, and a "character" is a 2-byte-stack (16 bit) all multibyte characters (3 and more bytes) will not work:
<script type="text/javascript">
var nonBmpString = "foo€";
console.log( nonBmpString.length );
// will output 5
</script>
The character "€" has a length of 3 bytes (24bit). Javascript does interpret it as 2 characters, because in JS, a character is a 16 bit block.
So to correctly get the bytesize of a mixed string, we have to code our own function fixedCharCodeAt();
function fixedCharCodeAt(str, idx) {
idx = idx || 0;
var code = str.charCodeAt(idx);
var hi, low;
if (0xD800 <= code && code <= 0xDBFF) { // High surrogate (could change last hex to 0xDB7F to treat high private surrogates as single characters)
hi = code;
low = str.charCodeAt(idx + 1);
if (isNaN(low)) {
throw 'Kein gültiges Schriftzeichen oder Speicherfehler!';
}
return ((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000;
}
if (0xDC00 <= code && code <= 0xDFFF) { // Low surrogate
// We return false to allow loops to skip this iteration since should have already handled high surrogate above in the previous iteration
return false;
/*hi = str.charCodeAt(idx-1);
low = code;
return ((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000;*/
}
return code;
}
Now we can count the bytes...
function countUtf8(str) {
var result = 0;
for (var n = 0; n < str.length; n++) {
var charCode = fixedCharCodeAt(str, n);
if (typeof charCode === "number") {
if (charCode < 128) {
result = result + 1;
} else if (charCode < 2048) {
result = result + 2;
} else if (charCode < 65536) {
result = result + 3;
} else if (charCode < 2097152) {
result = result + 4;
} else if (charCode < 67108864) {
result = result + 5;
} else {
result = result + 6;
}
}
}
return result;
}
By the way...
You should not use the encodeURI-method, because, it's a native browser function ;)
More stuff:
Code on GitHub
More on Mozilla Developer Networks
Cheers
frankneff.ch / #frank_neff
Add Byte length counting function to the string
String.prototype.Blength = function() {
var arr = this.match(/[^\x00-\xff]/ig);
return arr == null ? this.length : this.length + arr.length;
}
then you can use .Blength() to get the size
I have been asking myself the same thing. This is the best answer I have stumble upon:
http://www.inter-locale.com/demos/countBytes.html
Here is the code snippet:
<script type="text/javascript">
function checkLength() {
var countMe = document.getElementById("someText").value
var escapedStr = encodeURI(countMe)
if (escapedStr.indexOf("%") != -1) {
var count = escapedStr.split("%").length - 1
if (count == 0) count++ //perverse case; can't happen with real UTF-8
var tmp = escapedStr.length - (count * 3)
count = count + tmp
} else {
count = escapedStr.length
}
alert(escapedStr + ": size is " + count)
}
but the link contains a live example of it to play with. "encodeURI(STRING)" is the building block here, but also look at encodeURIComponent(STRING) (as already point out on the previous answer) to see which one fits your needs.
Regards
encodeURI(text).split(/%..|./).length - 1
How about simple:
unescape(encodeURIComponent(utf8text)).length
The trick is that encodeURIComponent seems to work on characters while unescape works on bytes.
Try the following:
function b(c) {
var n=0;
for (i=0;i<c.length;i++) {
p = c.charCodeAt(i);
if (p<128) {
n++;
} else if (p<2048) {
n+=2;
} else {
n+=3;
}
}return n;
}
set meta UTF-8 just & it's OK!
<meta charset="UTF-8">
<meta http-equiv="content-type" content="text/html;charset=utf-8">
and js:
if($mytext.length > 10){
// its okkk :)
}

Categories

Resources