Related
I've been learning javascript in school for a few months now and I'm trying to work a problem out on my own but I can't seem to figure out what the issue is. The assignment is to "Create a for loop that starts at zero and loops once for each character in the number using the .length property." So for example, if I were to put in 2514 it should return 12.
Here is the piece I'm struggling with
function sumOfDigits(numberPassed) {
if (!isNaturalNumber(numberPassed)) {
return 'bad data';
} else {
numberPassed = parseInt(numberPassed)
let digitSum = 0;
for (let i = 0; i < numberPassed.length; i++) {
digitSum = numberPassed[i] + digitSum;
}
return digitSum;
}
}
When I test it in the browser it keeps giving me 0. If anyone could point me in the right direction I would greatly appreciate it.
function sumOfDigits(numberPassed) {
if (!isNaturalNumber(numberPassed)) {
return 'bad data';
} else {
numberPassed = parseInt(numberPassed)
let digitSum = 0;
for (let i = 0; i < numberPassed.toString().length; i++) {
digitSum = numberPassed[i] + digitSum;
}
return digitSum;
}
}
It seems that your implementation is incredibly close to the solution that I found.
What the problem is, is that the value of parseInt(numberPassed) is no longer a string, which means its length cannot be read. So you have to one of many solutions. For example:
Make numberPassed a string in the for loop by doing for (let i = 0; i < numberPassed.toString().length; i++)
Don't parse the numberPassed until it is ready to be used as a number. Or create a secondary variable that is the same just set to a string.
There are many other solutions to this problems, but for the most part it is moving around the parseInt() or the .toString() around with the numberPassed, so to make it easier in the future you can use variables similar to intNumberPassed = parseInt(numberPassed) and stringNumberPassed = numberPassed.toString() if you need to switch between the two often
If you would like more of an explanation or more solutions to the problem here they are.
So when you have a string you can measure the length easily, but when you convert it to a number, instead of a list of binary numbers like a word would be, it is a singular value, aka 12 would be 1100 but when you convert it to a string '12' is would be equivalent to 00110001 00110010 which are the unicode to binary values for '12', giving us a length of two, instead of a length of one.
Do not parse your number string into an int, if you want to loop over each digit like it was an array.
function isNaturalNumber(numberStr) {
return /^\d+$/.test(numberStr);
}
function sumOfDigits(numberPassed) {
if (!isNaturalNumber(numberPassed)) {
return 'bad data';
}
let digitSum = 0;
for (let i = 0; i < numberPassed.length; i++) {
digitSum += parseInt(numberPassed[i], 10);
}
return digitSum;
}
console.log(sumOfDigits('2514')); // 12
If you want to parse it first, you will have to use some logarithmic math to extract each digit. String manipulation is less expensive in JavaScript, so this one is much-less performant.
function numDigits(n) {
return Math.max(Math.floor(Math.log10(Math.abs(n))), 0) + 1;
}
function getDigit(n, offset, fromLeft) {
const magnitude = fromLeft ? numDigits(n) - offset : offset + 1;
return Math.floor((n / Math.pow(10, magnitude - 1)) % 10);
}
function isNaturalNumber(numberStr) {
return /^\d+$/.test(numberStr);
}
function sumOfDigits(numberPassed) {
if (!isNaturalNumber(numberPassed)) {
return 'bad data';
}
const natural = parseInt(numberPassed, 10);
const digits = numDigits(natural);
let digitSum = 0;
for (let i = 0; i < digits; i++) {
digitSum += getDigit(natural, i);
}
return digitSum;
}
console.log(sumOfDigits('2514')); // 12
Credit for getDigit calculation: https://stackoverflow.com/a/41712226/1762224
If you want the most ES6 way to achieve this, give this a shot:
/**
* Determines if a given string is a natural number.
* #param {string} numStr - A number string
* #returns {boolean} The given string represents a natural number
*/
const isNaturalNumber = numStr => /^\d+$/.test(numStr)
/**
* Sums the digits of a given number or number string.
* #param {(number|string)} num - A number or number string
* #returns {number} The sum of all the digits
*/
const sumOfDigits = num =>
(numStr =>
isNaturalNumber(numStr)
? numStr.split('').reduce((sum, d) => sum + parseInt(d, 10), 0)
: 'bad data')
(num ? num.toString() : '')
console.log(sumOfDigits(2514)) // 12
console.log(sumOfDigits('2514')) // 12
console.log(sumOfDigits(5e2)) // 5
console.log(sumOfDigits('5e2')) // 'bad data'
parseInt() would convert numberPassed into a number. Thus, you wont be able to perform .length method to it.
You'd have to convert it into a string through, numberPassed.toString() and then while you are performing your addition, convert each digit back to INT through parseInt(numberPassed[i]) to get your desired result.
The code would look something like this,
function sumOfDigits(numberPassed) {
if (!isNaturalNumber(numberPassed)) {
return 'bad data';
} else {
numberPassed = numberPassed.toString()
let digitSum = 0;
for (let i = 0; i < numberPassed.length; i++) {
digitSum = parseInt(numberPassed[i]) + digitSum;
}
return digitSum;
}
}
Thanks to Nina I have a code to compare two sentences word by word and return the number of word matches like this:
function includeWords(wanted, seen) {
var wantedMap = wanted.split(/\s+/).reduce((m, s) => m.set(s, (m.get(s) || 0) + 1), new Map),
wantedArray = Array.from(wantedMap.keys()),
count = 0;
seen.split(/\s+/)
.forEach(s => {
var key = wantedArray.find(t => s === t || s.length > 3 && t.length > 3 && (s.startsWith(t) || t.startsWith(s)));
if (!wantedMap.get(key)) return;
console.log(s, key)
++count;
wantedMap.set(key, wantedMap.get(key) - 1);
});
return count;
}
let matches = includeWords('i was sent to earth to protect you introduced', 'they\'re were protecting him i knew that i was aware introducing');
console.log('Matched words: ' + matches);
The code works fine, but there is still one issue:
What if we want to return a match for introduced and introducing too?
If you want the program to consider the words 'introduce' and 'introducing' as a match, it would amount to a "fuzzy" match (non binary logic). One simple way of doing this would require more code, the algorithm of which would possibly resemble
Take 2 words that you wish to match, tokenize into ordered list
of letters
Compare positionally the respective letters, i.e
match a[0]==b[0]? a[1]==b[1] where a[0] represents the first letter
of the first word and b[0] represents the first tokenized
letter/character potential match candidate
KEep a rolling numeric count of such positional matches. In this case it is 8 (introduc).
divide by word length of a = 8/9 call this f
divide by word length of b = 8/11 call this g
Provide a threshold value beyond which the program will consider it a match. eg. if you say anything above 70% in BOTH f and g can be
considered a match - viola, you have your answer!
Please note that there is some normalization also needed to prevent low length words from becoming false positives. you can add a constraint that the aforementioned calculation applies to words with at least 5 letters(or something to that effect!
Hope this helps!!
Regards,
SR
You could calculate similarites for a word pair and get a relation how many characters are similar bei respecting the length of the given word and the wanted pattern.
function getSimilarity(a, b) {
var i = 0;
while (i < a.length) {
if (a[i] !== b[i]) break;
i++;
}
return i / Math.max(a.length, b.length);
}
console.log(getSimilarity('abcdefghij', 'abc')); // 0.3
console.log(getSimilarity('abcdefghij', 'abcdef')); // 0.6
console.log(getSimilarity('abcdefghij', 'abcdefghij')); // 1
console.log(getSimilarity('abcdef', 'abcdefghij')); // 0.6
console.log(getSimilarity('abcdefghij', 'abcdef')); // 0.6
console.log(getSimilarity('abcdefghij', 'xyz')); // 0
console.log(getSimilarity('introduced', 'introducing')); // 0.7272727272727273
Here's a quick fix solution.
It's not intended as a complete solution.
Since the English language has more than a few quirks that would almost require an AI to understand the language.
First add a function that can compare 2 words and returns a boolean.
It'll also make it easier to test for specific words, and adapt to what's really needed.
For example, here's a function that does the simple checks that were already used.
Plus an '...ed' versus '...ing' check.
function compareWords (word1, word2) {
if (word1 === word2)
return true;
if (word1.length > 3 && word2.length > 3) {
if (word1.startsWith(word2) || word2.startsWith(word1))
return true;
if (word1.length > 4 && word2.length > 4) {
if (/(ing|ed)$/.test(word1) && word1.replace(/(ing|ed)$/, 'inged') === word2.replace(/(ing|ed)$/, 'inged'))
return true;
}
}
return false;
}
//
// tests
//
let words = [
["same", "same"],
["different", "unsame"],
["priced", "pricing"],
["price", "priced"],
["producing", "produced"],
["produced", "producing"]
];
words.forEach( (arr, idx) => {
let word1= arr[0];
let word2= arr[1];
let isSame = compareWords(word1, word2);
console.log(`[${word1}] ā [${word2}] : ${isSame}`);
});
Then use it in the code you already have.
...
seen.split(/\s+/)
.forEach(s => {
var key = wantedArray.find(t => compareWords(t, s));
...
Regarding string similarity, here's f.e. an older SO post that has some methods to compare strings : Compare Strings Javascript Return %of Likely
I have implemented this, it seems to work fine. any suggestions would be appreciated..
let speechResult = "i was sent to earth to introducing protect yourself introduced seen";
let expectSt = ['they were protecting him knew introducing that you i seen was aware seen introducing'];
// Create arrays of words from above sentences
let speechResultWords = speechResult.split(/\s+/);
let expectStWords = expectSt[0].split(/\s+/);
function includeWords(){
// Declare a variable to hold the count number of matches
let arr = [];
for(let a = 0; a < speechResultWords.length; a++){
for(let b = 0; b < expectStWords.length; b++){
if(similarity(speechResultWords[a], expectStWords[b]) > 69){
arr.push(speechResultWords[a]);
console.log(speechResultWords[a] + ' includes in ' + expectStWords[b]);
}
} // End of first for loop
} // End of second for loop
let uniq = [...new Set(arr)];
return uniq.length;
};
let result = includeWords();
console.log(result)
// The algorithmn
function similarity(s1, s2) {
var longer = s1;
var shorter = s2;
if (s1.length < s2.length) {
longer = s2;
shorter = s1;
}
var longerLength = longer.length;
if (longerLength == 0) {
return 1.0;
}
return (longerLength - editDistance(longer, shorter)) / parseFloat(longerLength)*100;
}
function editDistance(s1, s2) {
s1 = s1.toLowerCase();
s2 = s2.toLowerCase();
var costs = new Array();
for (var i = 0; i <= s1.length; i++) {
var lastValue = i;
for (var j = 0; j <= s2.length; j++) {
if (i == 0)
costs[j] = j;
else {
if (j > 0) {
var newValue = costs[j - 1];
if (s1.charAt(i - 1) != s2.charAt(j - 1))
newValue = Math.min(Math.min(newValue, lastValue),
costs[j]) + 1;
costs[j - 1] = lastValue;
lastValue = newValue;
}
}
}
if (i > 0)
costs[s2.length] = lastValue;
}
return costs[s2.length];
}
Suppose I have a value of 15.7784514, I want to display it 15.77 with no rounding.
var num = parseFloat(15.7784514);
document.write(num.toFixed(1)+"<br />");
document.write(num.toFixed(2)+"<br />");
document.write(num.toFixed(3)+"<br />");
document.write(num.toFixed(10));
Results in -
15.8
15.78
15.778
15.7784514000
How do I display 15.77?
Convert the number into a string, match the number up to the second decimal place:
function calc(theform) {
var num = theform.original.value, rounded = theform.rounded
var with2Decimals = num.toString().match(/^-?\d+(?:\.\d{0,2})?/)[0]
rounded.value = with2Decimals
}
<form onsubmit="return calc(this)">
Original number: <input name="original" type="text" onkeyup="calc(form)" onchange="calc(form)" />
<br />"Rounded" number: <input name="rounded" type="text" placeholder="readonly" readonly>
</form>
The toFixed method fails in some cases unlike toString, so be very careful with it.
Update 5 Nov 2016
New answer, always accurate
function toFixed(num, fixed) {
var re = new RegExp('^-?\\d+(?:\.\\d{0,' + (fixed || -1) + '})?');
return num.toString().match(re)[0];
}
As floating point math in javascript will always have edge cases, the previous solution will be accurate most of the time which is not good enough.
There are some solutions to this like num.toPrecision, BigDecimal.js, and accounting.js.
Yet, I believe that merely parsing the string will be the simplest and always accurate.
Basing the update on the well written regex from the accepted answer by #Gumbo, this new toFixed function will always work as expected.
Old answer, not always accurate.
Roll your own toFixed function:
function toFixed(num, fixed) {
fixed = fixed || 0;
fixed = Math.pow(10, fixed);
return Math.floor(num * fixed) / fixed;
}
Another single-line solution :
number = Math.trunc(number*100)/100
I used 100 because you want to truncate to the second digit, but a more flexible solution would be :
number = Math.trunc(number*Math.pow(10, digits))/Math.pow(10, digits)
where digits is the amount of decimal digits to keep.
See Math.trunc specs for details and browser compatibility.
I opted to write this instead to manually remove the remainder with strings so I don't have to deal with the math issues that come with numbers:
num = num.toString(); //If it's not already a String
num = num.slice(0, (num.indexOf("."))+3); //With 3 exposing the hundredths place
Number(num); //If you need it back as a Number
This will give you "15.77" with num = 15.7784514;
Update (Jan 2021)
Depending on its range, a number in javascript may be shown in scientific notation. For example, if you type 0.0000001 in the console, you may see it as 1e-7, whereas 0.000001 appears unchanged (0.000001).
If your application works on a range of numbers for which scientific notation is not involved, you can just ignore this update and use the original answer below.
This update is about adding a function that checks if the number is in scientific format and, if so, converts it into decimal format. Here I'm proposing this one, but you can use any other function that achieves the same goal, according to your application's needs:
function toFixed(x) {
if (Math.abs(x) < 1.0) {
let e = parseInt(x.toString().split('e-')[1]);
if (e) {
x *= Math.pow(10,e-1);
x = '0.' + (new Array(e)).join('0') + x.toString().substring(2);
}
} else {
let e = parseInt(x.toString().split('+')[1]);
if (e > 20) {
e -= 20;
x /= Math.pow(10,e);
x += (new Array(e+1)).join('0');
}
}
return x;
}
Now just apply that function to the parameter (that's the only change with respect to the original answer):
function toFixedTrunc(x, n) {
x = toFixed(x)
// From here on the code is the same than the original answer
const v = (typeof x === 'string' ? x : x.toString()).split('.');
if (n <= 0) return v[0];
let f = v[1] || '';
if (f.length > n) return `${v[0]}.${f.substr(0,n)}`;
while (f.length < n) f += '0';
return `${v[0]}.${f}`
}
This updated version addresses also a case mentioned in a comment:
toFixedTrunc(0.000000199, 2) => "0.00"
Again, choose what fits your application needs at best.
Original answer (October 2017)
General solution to truncate (no rounding) a number to the n-th decimal digit and convert it to a string with exactly n decimal digits, for any nā„0.
function toFixedTrunc(x, n) {
const v = (typeof x === 'string' ? x : x.toString()).split('.');
if (n <= 0) return v[0];
let f = v[1] || '';
if (f.length > n) return `${v[0]}.${f.substr(0,n)}`;
while (f.length < n) f += '0';
return `${v[0]}.${f}`
}
where x can be either a number (which gets converted into a string) or a string.
Here are some tests for n=2 (including the one requested by OP):
0 => 0.00
0.01 => 0.01
0.5839 => 0.58
0.999 => 0.99
1.01 => 1.01
2 => 2.00
2.551 => 2.55
2.99999 => 2.99
4.27 => 4.27
15.7784514 => 15.77
123.5999 => 123.59
And for some other values of n:
15.001097 => 15.0010 (n=4)
0.000003298 => 0.0000032 (n=7)
0.000003298257899 => 0.000003298257 (n=12)
parseInt is faster then Math.floor
function floorFigure(figure, decimals){
if (!decimals) decimals = 2;
var d = Math.pow(10,decimals);
return (parseInt(figure*d)/d).toFixed(decimals);
};
floorFigure(123.5999) => "123.59"
floorFigure(123.5999, 3) => "123.599"
num = 19.66752
f = num.toFixed(3).slice(0,-1)
alert(f)
This will return 19.66
Simple do this
number = parseInt(number * 100)/100;
Just truncate the digits:
function truncDigits(inputNumber, digits) {
const fact = 10 ** digits;
return Math.floor(inputNumber * fact) / fact;
}
This is not a safe alternative, as many others commented examples with numbers that turn into exponential notation, that scenery is not covered by this function
// typescript
// function formatLimitDecimals(value: number, decimals: number): number {
function formatLimitDecimals(value, decimals) {
const stringValue = value.toString();
if(stringValue.includes('e')) {
// TODO: remove exponential notation
throw 'invald number';
} else {
const [integerPart, decimalPart] = stringValue.split('.');
if(decimalPart) {
return +[integerPart, decimalPart.slice(0, decimals)].join('.')
} else {
return integerPart;
}
}
}
console.log(formatLimitDecimals(4.156, 2)); // 4.15
console.log(formatLimitDecimals(4.156, 8)); // 4.156
console.log(formatLimitDecimals(4.156, 0)); // 4
console.log(formatLimitDecimals(0, 4)); // 0
// not covered
console.log(formatLimitDecimals(0.000000199, 2)); // 0.00
These solutions do work, but to me seem unnecessarily complicated. I personally like to use the modulus operator to obtain the remainder of a division operation, and remove that. Assuming that num = 15.7784514:
num-=num%.01;
This is equivalent to saying num = num - (num % .01).
I fixed using following simple way-
var num = 15.7784514;
Math.floor(num*100)/100;
Results will be 15.77
My version for positive numbers:
function toFixed_norounding(n,p)
{
var result = n.toFixed(p);
return result <= n ? result: (result - Math.pow(0.1,p)).toFixed(p);
}
Fast, pretty, obvious. (version for positive numbers)
The answers here didn't help me, it kept rounding up or giving me the wrong decimal.
my solution converts your decimal to a string, extracts the characters and then returns the whole thing as a number.
function Dec2(num) {
num = String(num);
if(num.indexOf('.') !== -1) {
var numarr = num.split(".");
if (numarr.length == 1) {
return Number(num);
}
else {
return Number(numarr[0]+"."+numarr[1].charAt(0)+numarr[1].charAt(1));
}
}
else {
return Number(num);
}
}
Dec2(99); // 99
Dec2(99.9999999); // 99.99
Dec2(99.35154); // 99.35
Dec2(99.8); // 99.8
Dec2(10265.985475); // 10265.98
The following code works very good for me:
num.toString().match(/.\*\\..{0,2}|.\*/)[0];
This worked well for me. I hope it will fix your issues too.
function toFixedNumber(number) {
const spitedValues = String(number.toLocaleString()).split('.');
let decimalValue = spitedValues.length > 1 ? spitedValues[1] : '';
decimalValue = decimalValue.concat('00').substr(0,2);
return '$'+spitedValues[0] + '.' + decimalValue;
}
// 5.56789 ----> $5.56
// 0.342 ----> $0.34
// -10.3484534 ----> $-10.34
// 600 ----> $600.00
function convertNumber(){
var result = toFixedNumber(document.getElementById("valueText").value);
document.getElementById("resultText").value = result;
}
function toFixedNumber(number) {
const spitedValues = String(number.toLocaleString()).split('.');
let decimalValue = spitedValues.length > 1 ? spitedValues[1] : '';
decimalValue = decimalValue.concat('00').substr(0,2);
return '$'+spitedValues[0] + '.' + decimalValue;
}
<div>
<input type="text" id="valueText" placeholder="Input value here..">
<br>
<button onclick="convertNumber()" >Convert</button>
<br><hr>
<input type="text" id="resultText" placeholder="result" readonly="true">
</div>
An Easy way to do it is the next but is necessary ensure that the amount parameter is given as a string.
function truncate(amountAsString, decimals = 2){
var dotIndex = amountAsString.indexOf('.');
var toTruncate = dotIndex !== -1 && ( amountAsString.length > dotIndex + decimals + 1);
var approach = Math.pow(10, decimals);
var amountToTruncate = toTruncate ? amountAsString.slice(0, dotIndex + decimals +1) : amountAsString;
return toTruncate
? Math.floor(parseFloat(amountToTruncate) * approach ) / approach
: parseFloat(amountAsString);
}
console.log(truncate("7.99999")); //OUTPUT ==> 7.99
console.log(truncate("7.99999", 3)); //OUTPUT ==> 7.999
console.log(truncate("12.799999999999999")); //OUTPUT ==> 7.99
Here you are. An answer that shows yet another way to solve the problem:
// For the sake of simplicity, here is a complete function:
function truncate(numToBeTruncated, numOfDecimals) {
var theNumber = numToBeTruncated.toString();
var pointIndex = theNumber.indexOf('.');
return +(theNumber.slice(0, pointIndex > -1 ? ++numOfDecimals + pointIndex : undefined));
}
Note the use of + before the final expression. That is to convert our truncated, sliced string back to number type.
Hope it helps!
truncate without zeroes
function toTrunc(value,n){
return Math.floor(value*Math.pow(10,n))/(Math.pow(10,n));
}
or
function toTrunc(value,n){
x=(value.toString()+".0").split(".");
return parseFloat(x[0]+"."+x[1].substr(0,n));
}
test:
toTrunc(17.4532,2) //17.45
toTrunc(177.4532,1) //177.4
toTrunc(1.4532,1) //1.4
toTrunc(.4,2) //0.4
truncate with zeroes
function toTruncFixed(value,n){
return toTrunc(value,n).toFixed(n);
}
test:
toTrunc(17.4532,2) //17.45
toTrunc(177.4532,1) //177.4
toTrunc(1.4532,1) //1.4
toTrunc(.4,2) //0.40
If you exactly wanted to truncate to 2 digits of precision, you can go with a simple logic:
function myFunction(number) {
var roundedNumber = number.toFixed(2);
if (roundedNumber > number)
{
roundedNumber = roundedNumber - 0.01;
}
return roundedNumber;
}
I used (num-0.05).toFixed(1) to get the second decimal floored.
It's more reliable to get two floating points without rounding.
Reference Answer
var number = 10.5859;
var fixed2FloatPoints = parseInt(number * 100) / 100;
console.log(fixed2FloatPoints);
Thank You !
My solution in typescript (can easily be ported to JS):
/**
* Returns the price with correct precision as a string
*
* #param price The price in decimal to be formatted.
* #param decimalPlaces The number of decimal places to use
* #return string The price in Decimal formatting.
*/
type toDecimal = (price: number, decimalPlaces?: number) => string;
const toDecimalOdds: toDecimal = (
price: number,
decimalPlaces: number = 2,
): string => {
const priceString: string = price.toString();
const pointIndex: number = priceString.indexOf('.');
// Return the integer part if decimalPlaces is 0
if (decimalPlaces === 0) {
return priceString.substr(0, pointIndex);
}
// Return value with 0s appended after decimal if the price is an integer
if (pointIndex === -1) {
const padZeroString: string = '0'.repeat(decimalPlaces);
return `${priceString}.${padZeroString}`;
}
// If numbers after decimal are less than decimalPlaces, append with 0s
const padZeroLen: number = priceString.length - pointIndex - 1;
if (padZeroLen > 0 && padZeroLen < decimalPlaces) {
const padZeroString: string = '0'.repeat(padZeroLen);
return `${priceString}${padZeroString}`;
}
return priceString.substr(0, pointIndex + decimalPlaces + 1);
};
Test cases:
expect(filters.toDecimalOdds(3.14159)).toBe('3.14');
expect(filters.toDecimalOdds(3.14159, 2)).toBe('3.14');
expect(filters.toDecimalOdds(3.14159, 0)).toBe('3');
expect(filters.toDecimalOdds(3.14159, 10)).toBe('3.1415900000');
expect(filters.toDecimalOdds(8.2)).toBe('8.20');
Any improvements?
Another solution, that truncates and round:
function round (number, decimals, truncate) {
if (truncate) {
number = number.toFixed(decimals + 1);
return parseFloat(number.slice(0, -1));
}
var n = Math.pow(10.0, decimals);
return Math.round(number * n) / n;
};
function limitDecimalsWithoutRounding(val, decimals){
let parts = val.toString().split(".");
return parseFloat(parts[0] + "." + parts[1].substring(0, decimals));
}
var num = parseFloat(15.7784514);
var new_num = limitDecimalsWithoutRounding(num, 2);
Roll your own toFixed function: for positive values Math.floor works fine.
function toFixed(num, fixed) {
fixed = fixed || 0;
fixed = Math.pow(10, fixed);
return Math.floor(num * fixed) / fixed;
}
For negative values Math.floor is round of the values. So you can use Math.ceil instead.
Example,
Math.ceil(-15.778665 * 10000) / 10000 = -15.7786
Math.floor(-15.778665 * 10000) / 10000 = -15.7787 // wrong.
Gumbo's second solution, with the regular expression, does work but is slow because of the regular expression. Gumbo's first solution fails in certain situations due to imprecision in floating points numbers. See the JSFiddle for a demonstration and a benchmark. The second solution takes about 1636 nanoseconds per call on my current system, Intel Core i5-2500 CPU at 3.30 GHz.
The solution I've written involves adding a small compensation to take care of floating point imprecision. It is basically instantaneous, i.e. on the order of nanoseconds. I clocked 2 nanoseconds per call but the JavaScript timers are not very precise or granular. Here is the JS Fiddle and the code.
function toFixedWithoutRounding (value, precision)
{
var factorError = Math.pow(10, 14);
var factorTruncate = Math.pow(10, 14 - precision);
var factorDecimal = Math.pow(10, precision);
return Math.floor(Math.floor(value * factorError + 1) / factorTruncate) / factorDecimal;
}
var values = [1.1299999999, 1.13, 1.139999999, 1.14, 1.14000000001, 1.13 * 100];
for (var i = 0; i < values.length; i++)
{
var value = values[i];
console.log(value + " --> " + toFixedWithoutRounding(value, 2));
}
for (var i = 0; i < values.length; i++)
{
var value = values[i];
console.log(value + " --> " + toFixedWithoutRounding(value, 4));
}
console.log("type of result is " + typeof toFixedWithoutRounding(1.13 * 100 / 100, 2));
// Benchmark
var value = 1.13 * 100;
var startTime = new Date();
var numRun = 1000000;
var nanosecondsPerMilliseconds = 1000000;
for (var run = 0; run < numRun; run++)
toFixedWithoutRounding(value, 2);
var endTime = new Date();
var timeDiffNs = nanosecondsPerMilliseconds * (endTime - startTime);
var timePerCallNs = timeDiffNs / numRun;
console.log("Time per call (nanoseconds): " + timePerCallNs);
Building on David D's answer:
function NumberFormat(num,n) {
var num = (arguments[0] != null) ? arguments[0] : 0;
var n = (arguments[1] != null) ? arguments[1] : 2;
if(num > 0){
num = String(num);
if(num.indexOf('.') !== -1) {
var numarr = num.split(".");
if (numarr.length > 1) {
if(n > 0){
var temp = numarr[0] + ".";
for(var i = 0; i < n; i++){
if(i < numarr[1].length){
temp += numarr[1].charAt(i);
}
}
num = Number(temp);
}
}
}
}
return Number(num);
}
console.log('NumberFormat(123.85,2)',NumberFormat(123.85,2));
console.log('NumberFormat(123.851,2)',NumberFormat(123.851,2));
console.log('NumberFormat(0.85,2)',NumberFormat(0.85,2));
console.log('NumberFormat(0.851,2)',NumberFormat(0.851,2));
console.log('NumberFormat(0.85156,2)',NumberFormat(0.85156,2));
console.log('NumberFormat(0.85156,4)',NumberFormat(0.85156,4));
console.log('NumberFormat(0.85156,8)',NumberFormat(0.85156,8));
console.log('NumberFormat(".85156",2)',NumberFormat(".85156",2));
console.log('NumberFormat("0.85156",2)',NumberFormat("0.85156",2));
console.log('NumberFormat("1005.85156",2)',NumberFormat("1005.85156",2));
console.log('NumberFormat("0",2)',NumberFormat("0",2));
console.log('NumberFormat("",2)',NumberFormat("",2));
console.log('NumberFormat(85156,8)',NumberFormat(85156,8));
console.log('NumberFormat("85156",2)',NumberFormat("85156",2));
console.log('NumberFormat("85156.",2)',NumberFormat("85156.",2));
// NumberFormat(123.85,2) 123.85
// NumberFormat(123.851,2) 123.85
// NumberFormat(0.85,2) 0.85
// NumberFormat(0.851,2) 0.85
// NumberFormat(0.85156,2) 0.85
// NumberFormat(0.85156,4) 0.8515
// NumberFormat(0.85156,8) 0.85156
// NumberFormat(".85156",2) 0.85
// NumberFormat("0.85156",2) 0.85
// NumberFormat("1005.85156",2) 1005.85
// NumberFormat("0",2) 0
// NumberFormat("",2) 0
// NumberFormat(85156,8) 85156
// NumberFormat("85156",2) 85156
// NumberFormat("85156.",2) 85156
Already there are some suitable answer with regular expression and arithmetic calculation, you can also try this
function myFunction() {
var str = 12.234556;
str = str.toString().split('.');
var res = str[1].slice(0, 2);
document.getElementById("demo").innerHTML = str[0]+'.'+res;
}
// output: 12.23
Here is what is did it with string
export function withoutRange(number) {
const str = String(number);
const dotPosition = str.indexOf('.');
if (dotPosition > 0) {
const length = str.substring().length;
const end = length > 3 ? 3 : length;
return str.substring(0, dotPosition + end);
}
return str;
}
I wonder how to write palindrome in javascript, where I input different words and program shows if word is palindrome or not. For example word noon is palindrome, while bad is not.
Thank you in advance.
function palindrome(str) {
var len = str.length;
var mid = Math.floor(len/2);
for ( var i = 0; i < mid; i++ ) {
if (str[i] !== str[len - 1 - i]) {
return false;
}
}
return true;
}
palindrome will return if specified word is palindrome, based on boolean value (true/false)
UPDATE:
I opened bounty on this question due to performance and I've done research and here are the results:
If we are dealing with very large amount of data like
var abc = "asdhfkahkjdfhkaksjdfhaksdfjhakjddfhkjahksdhfaiuyqewiuryiquweyriyqiuweyriuqiuweryiquweyriuqyweirukajsdhfkahdfjkhakjsdhfkahksdhfakhdjkfqwiueryqiueyriuasdkfjhakjhdfkjashfkajhsdfkjahsdkalsdjflkasjdfljqoiweurasldjflasfdasdhfkahkjdfhkaksjdfhaksdfjhakjddfhkjahksdhfaiuyqewiuryiquweyriyqiuweyriuqiuweryiquweyriuqyweirukajsdhfkahdfjkhakjsdhfkahksdhfakhdjkfqwiueryqiueyriuasdkfjhakjhdfkjashfkajhsdfkjahsdkalsdjflkasjdfljqoiweurasldjflasfdasdhfkahkjdfhkaksjdfhaksdfjhakjddfhkjahksdhfaiuyqewiuryiquweyriyqiuweyriuqiuweryiquweyriuqyweirukajsdhfkahdfjkhakjsdhfkahksdhfakhdjkfqwiueryqiueyriuasdkfjhakjhdfkjashfkajhsdfkjahsdkalsdjflkasjdfljqoiweurasldjflasfdasdhfkahkjdfhkaksjdfhaksdfjhakjddfhkjahksdhfaiuyqewiuryiquweyriyqiuweyriuqiuweryiquweyriuqyweirukajsdhfkahdfjkhakjsdhfkahksdhfakhdjkfqwiueryqiueyriuasdkfjhakjhdfkjashfkajhsdfkjahsdkalsdjflkasjdfljqoiweurasldjflasfdasdhfkahkjdfhkaksjdfhaksdfjhakjddfhkjahksdhfaiuyqewiuryiquweyriyqiuweyriuqiuweryiquweyriuqyweirukajsdhfkahdfjkhakjsdhfkahksdhfakhdjkfqwiueryqiueyriuasdkfjhakjhdfkjashfkajhsdfkjahsdkalsdjflkasjdfljqoiweurasldjflasfdasdhfkahkjdfhkaksjdfhaksdfjhakjddfhkjahksdhfaiuyqewiuryiquweyriyqiuweyriuqiuweryiquweyriuqyweirukajsdhfkahdfjkhakjsdhfkahksdhfakhdjkfqwiueryqiueyriuasdkfjhakjhdfkjashfkajhsdfkjahsdkalsdjflkasjdfljqoiweurasldjflasfdasdhfkahkjdfhkaksjdfhaksdfjhakjddfhkjahksdhfaiuyqewiuryiquweyriyqiuweyriuqiuweryiquweyriuqyweirukajsdhfkahdfjkhakjsdhfkahksdhfakhdjkfqwiueryqiueyriuasdkfjhakjhdfkjashfkajhsdfkjahsdkalsdjflkasjdfljqoiweurasldjflasfdasdhfkahkjdfhkaksjdfhaksdfjhakjddfhkjahksdhfaiuyqewiuryiquweyriyqiuweyriuqiuweryiquweyriuqyweirukajsdhfkahdfjkhakjsdhfkahksdhfakhdjkfqwiueryqiueyriuasdkfjhakjhdfkjashfkajhsdfkjahsdkalsdjflkasjdfljqoiweurasldjflasfdasdhfkahkjdfhkaksjdfhaksdfjhakjddfhkjahksdhfaiuyqewiuryiquweyriyqiuweyriuqiuweryiquweyriuqyweirukajsdhfkahdfjkhakjsdhfkahksdhfakhdjkfqwiueryqiueyriuasdkfjhakjhdfkjashfkajhsdfkjahsdkalsdjflkasjdfljqoiweurasldjflasfdasdhfkahkjdfhkaksjdfhaksdfjhakjddfhkjahksdhfaiuyqewiuryiquweyriyqiuweyriuqiuweryiquweyriuqyweirukajsdhfkahdfjkhakjsdhfkahksdhfakhdjkfqwiueryqiueyriuasdkfjhakjhdfkjashfkajhsdfkjahsdkalsdjflkasjdfljqoiweurasldjflasfdasdhfkahkjdfhkaksjdfhaksdfjhakjddfhkjahksdhfaiuyqewiuryiquweyriyqiuweyriuqiuweryiquweyriuqyweirukajsdhfkahdfjkhakjsdhfkahksdhfakhdjkfqwiueryqiueyriuasdkfjhakjhdfkjashfkajhsdfkjahsdkalsdjflkasjdfljqoiweurasldjflasfdasdhfkahkjdfhkaksjdfhaksdfjhakjddfhkjahksdhfaiuyqewiuryiquweyriyqiuweyriuqiuweryiquweyriuqyweirukajsdhfkahdfjkhakjsdhfkahksdhfakhdjkfqwiueryqiueyriuasdkfjhakjhdfkjashfkajhsdfkjahsdkalsdjflkasjdfljqoiweurasldjflasfdasdhfkahkjdfhkaksjdfhaksdfjhakjddfhkjahksdhfaiuyqewiuryiquweyriyqiuweyriuqiuweryiquweyriuqyweirukajsdhfkahdfjkhakjsdhfkahksdhfakhdjkfqwiueryqiueyriuasdkfjhakjhdfkjashfkajhsdfkjahsdkalsdjflkasjdfljqoiweurasldjflasfdasdhfkahkjdfhkaksjdfhaksdfjhakjddfhkjahksdhfaiuyqewiuryiquweyriyqiuweyriuqiuweryiquweyriuqyweirukajsdhfkahdfjkhakjsdhfkahksdhfakhdjkfqwiueryqiueyriuasdkfjhakjhdfkjashfkajhsdfkjahsdkalsdjflkasjdfljqoiweurasldjflasfdasdhfkahkjdfhkaksjdfhaksdfjhakjddfhkjahksdhfaiuyqewiuryiquweyriyqiuweyriuqiuweryiquweyriuqyweirukajsdhfkahdfjkhakjsdhfkahksdhfakhdjkfqwiueryqiueyriuasdkfjhakjhdfkjashfkajhsdfkjahsdkalsdjflkasjdfljqoiweurasldjflasfdasdhfkahkjdfhkaksjdfhaksdfjhakjddfhkjahksdhfaiuyqewiuryiquweyriyqiuweyriuqiuweryiquweyriuqyweirukajsdhfkahdfjkhakjsdhfkahksdhfakhdjkfqwiueryqiueyriuasdkfjhakjhdfkjashfkajhsdfkjahsdkalsdjflkasjdfljqoiweurasldjflasfdasdhfkahkjdfhkaksjdfhaksdfjhakjddfhkjahksdhfaiuyqewiuryiquweyriyqiuweyriuqiuweryiquweyriuqyweirukajsdhfkahdfjkhakjsdhfkahksdhfakhdjkfqwiueryqiueyriuasdkfjhakjhdfkjashfkajhsdfkjahsdkalsdjflkasjdfljqoiweurasldjflasfdasdhfkahkjdfhkaksjdfhaksdfjhakjddfhkjahksdhfaiuyqewiuryiquweyriyqiuweyriuqiuweryiquweyriuqyweirukajsdhfkahdfjkhakjsdhfkahksdhfakhdjkfqwiueryqiueyriuasdkfjhakjhdfkjashfkajhsdfkjahsdkalsdjflkasjdfljqoiweurasldjflasfdasdhfkahkjdfhkaksjdfhaksdfjhakjddfhkjahksdhfaiuyqewiuryiquweyriyqiuweyriuqiuweryiquweyriuqyweirukajsdhfkahdfjkhakjsdhfkahksdhfakhdjkfqwiueryqiueyriuasdkfjhakjhdfkjashfkajhsdfkjahsdkalsdjflkasjdfljqoiweurasldjflasfdasdhfkahkjdfhkaksjdfhaksdfjhakjddfhkjahksdhfaiuyqewiuryiquweyriyqiuweyriuqiuweryiquweyriuqyweirukajsdhfkahdfjkhakjsdhfkahksdhfakhdjkfqwiueryqiueyriuasdkfjhakjhdfkjashfkajhsdfkjahsdkalsdjflkasjdfljqoiweurasldjflasfdasdhfkahkjdfhkaksjdfhaksdfjhakjddfhkjahksdhfaiuyqewiuryiquweyriyqiuweyriuqiuweryiquweyriuqyweirukajsdhfkahdfjkhakjsdhfkahksdhfakhdjkfqwiueryqiueyriuasdkfjhakjhdfkjashfkajhsdfkjahsdkalsdjflkasjdfljqoiweurasldjflasfd";
for ( var i = 0; i < 10; i++ ) {
abc += abc; // making string even more larger
}
function reverse(s) { // using this method for second half of string to be embedded
return s.split("").reverse().join("");
}
abc += reverse(abc); // adding second half string to make string true palindrome
In this example palindrome is True, just to note
Posted palindrome function gives us time from 180 to 210 Milliseconds (in current example), and the function posted below
with string == string.split('').reverse().join('') method gives us 980 to 1010 Milliseconds.
Machine Details:
System: Ubuntu 13.10
OS Type: 32 Bit
RAM: 2 Gb
CPU: 3.4 Ghz*2
Browser: Firefox 27.0.1
Try this:
var isPalindrome = function (string) {
if (string == string.split('').reverse().join('')) {
alert(string + ' is palindrome.');
}
else {
alert(string + ' is not palindrome.');
}
}
document.getElementById('form_id').onsubmit = function() {
isPalindrome(document.getElementById('your_input').value);
}
So this script alerts the result, is it palindrome or not. You need to change the your_id with your input id and form_id with your form id to get this work.
Demo!
Use something like this
function isPalindrome(s) {
return s === s.split("").reverse().join("") ? true : false;
}
alert(isPalindrome("noon"));
alternatively the above code can be optimized as [updated after rightfold's comment]
function isPalindrome(s) {
return s === s.split("").reverse().join("");
}
alert(isPalindrome("malayalam"));
alert(isPalindrome("english"));
Faster Way:
-Compute half the way in loop.
-Store length of the word in a variable instead of calculating every time.
EDIT:
Store word length/2 in a temporary variable as not to calculate every time in the loop as pointed out by (mvw) .
function isPalindrome(word){
var i,wLength = word.length-1,wLengthToCompare = wLength/2;
for (i = 0; i <= wLengthToCompare ; i++) {
if (word.charAt(i) != word.charAt(wLength-i)) {
return false;
}
}
return true;
}
Let us start from the recursive definition of a palindrome:
The empty string '' is a palindrome
The string consisting of the character c, thus 'c', is a palindrome
If the string s is a palindrome, then the string 'c' + s + 'c' for some character c is a palindrome
This definition can be coded straight into JavaScript:
function isPalindrome(s) {
var len = s.length;
// definition clauses 1. and 2.
if (len < 2) {
return true;
}
// note: len >= 2
// definition clause 3.
if (s[0] != s[len - 1]) {
return false;
}
// note: string is of form s = 'a' + t + 'a'
// note: s.length >= 2 implies t.length >= 0
var t = s.substr(1, len - 2);
return isPalindrome(t);
}
Here is some additional test code for MongoDB's mongo JavaScript shell, in a web browser with debugger replace print() with console.log()
function test(s) {
print('isPalindrome(' + s + '): ' + isPalindrome(s));
}
test('');
test('a');
test('ab');
test('aa');
test('aab');
test('aba');
test('aaa');
test('abaa');
test('neilarmstronggnortsmralien');
test('neilarmstrongxgnortsmralien');
test('neilarmstrongxsortsmralien');
I got this output:
$ mongo palindrome.js
MongoDB shell version: 2.4.8
connecting to: test
isPalindrome(): true
isPalindrome(a): true
isPalindrome(ab): false
isPalindrome(aa): true
isPalindrome(aab): false
isPalindrome(aba): true
isPalindrome(aaa): true
isPalindrome(abaa): false
isPalindrome(neilarmstronggnortsmralien): true
isPalindrome(neilarmstrongxgnortsmralien): true
isPalindrome(neilarmstrongxsortsmralien): false
An iterative solution is:
function isPalindrome(s) {
var len = s.length;
if (len < 2) {
return true;
}
var i = 0;
var j = len - 1;
while (i < j) {
if (s[i] != s[j]) {
return false;
}
i += 1;
j -= 1;
}
return true;
}
Look at this:
function isPalindrome(word){
if(word==null || word.length==0){
// up to you if you want true or false here, don't comment saying you
// would put true, I put this check here because of
// the following i < Math.ceil(word.length/2) && i< word.length
return false;
}
var lastIndex=Math.ceil(word.length/2);
for (var i = 0; i < lastIndex && i< word.length; i++) {
if (word[i] != word[word.length-1-i]) {
return false;
}
}
return true;
}
Edit: now half operation of comparison are performed since I iterate only up to half word to compare it with the last part of the word. Faster for large data!!!
Since the string is an array of char no need to use charAt functions!!!
Reference: http://wiki.answers.com/Q/Javascript_code_for_palindrome
Taking a stab at this. Kind of hard to measure performance, though.
function palin(word) {
var i = 0,
len = word.length - 1,
max = word.length / 2 | 0;
while (i < max) {
if (word.charCodeAt(i) !== word.charCodeAt(len - i)) {
return false;
}
i += 1;
}
return true;
}
My thinking is to use charCodeAt() instead charAt() with the hope that allocating a Number instead of a String will have better perf because Strings are variable length and might be more complex to allocate. Also, only iterating halfway through (as noted by sai) because that's all that's required. Also, if the length is odd (ex: 'aba'), the middle character is always ok.
Best Way to check string is palindrome with more criteria like case and special characters...
function checkPalindrom(str) {
var str = str.replace(/[^a-zA-Z0-9]+/gi, '').toLowerCase();
return str == str.split('').reverse().join('');
}
You can test it with following words and strings and gives you more specific result.
1. bob
2. Doc, note, I dissent. A fast never prevents a fatness. I diet on cod
For strings it ignores special characters and convert string to lower case.
String.prototype.isPalindrome = function isPalindrome() {
const cleanString = this.toLowerCase().replace(/\s+/g, '');
const cleanStringRevers = cleanString.split("").reverse().join("");
return cleanString === cleanStringRevers;
}
let nonPalindrome = 'not a palindrome';
let palindrome = 'sugus';
console.log(nonPalindrome.isPalindrome())
console.log(palindrome.isPalindrome())
The most important thing to do when solving a Technical Test is Don't use shortcut methods -- they want to see how you think algorithmically! Not your use of methods.
Here is one that I came up with (45 minutes after I blew the test). There are a couple optimizations to make though. When writing any algorithm, its best to assume false and alter the logic if its looking to be true.
isPalindrome():
Basically, to make this run in O(N) (linear) complexity you want to have 2 iterators whose vectors point towards each other. Meaning, one iterator that starts at the beginning and one that starts at the end, each traveling inward. You could have the iterators traverse the whole array and use a condition to break/return once they meet in the middle, but it may save some work to only give each iterator a half-length by default.
for loops seem to force the use of more checks, so I used while loops - which I'm less comfortable with.
Here's the code:
/**
* TODO: If func counts out, let it return 0
* * Assume !isPalindrome (invert logic)
*/
function isPalindrome(S){
var s = S
, len = s.length
, mid = len/2;
, i = 0, j = len-1;
while(i<mid){
var l = s.charAt(i);
while(j>=mid){
var r = s.charAt(j);
if(l === r){
console.log('#while *', i, l, '...', j, r);
--j;
break;
}
console.log('#while !', i, l, '...', j, r);
return 0;
}
++i;
}
return 1;
}
var nooe = solution('neveroddoreven'); // even char length
var kayak = solution('kayak'); // odd char length
var kayaks = solution('kayaks');
console.log('#isPalindrome', nooe, kayak, kayaks);
Notice that if the loops count out, it returns true. All the logic should be inverted so that it by default returns false. I also used one short cut method String.prototype.charAt(n), but I felt OK with this as every language natively supports this method.
This function will remove all non-alphanumeric characters (punctuation, spaces, and symbols) and turn everything lower case in order to check for palindromes.
function palindrome(str){
var re = /[^A-Za-z0-9]/g;
str = str.toLowerCase().replace(re, '');
return str == str.split('').reverse().join('') ? true : false;
}
Here is an optimal and robust solution for checking string palindrome using ES6 features.
const str="madam"
var result=[...str].reduceRight((c,v)=>((c+v)))==str?"Palindrome":"Not Palindrome";
console.log(result);
Try this
isPalindrome = (string) => {
if (string === string.split('').reverse().join('')) {
console.log('is palindrome');
}
else {
console.log('is not palindrome');
}
}
isPalindrome(string)
Here's a one-liner without using String.reverse,
const isPal = str => [...new Array(strLen = str.length)]
.reduce((acc, s, i) => acc + str[strLen - (i + 1)], '') === str;
function palindrome(str) {
var lenMinusOne = str.length - 1;
var halfLen = Math.floor(str.length / 2);
for (var i = 0; i < halfLen; ++i) {
if (str[i] != str[lenMinusOne - i]) {
return false;
}
}
return true;
}
Optimized for half string parsing and for constant value variables.
I think following function with time complexity of o(log n) will be better.
function palindrom(s){
s = s.toString();
var f = true; l = s.length/2, len = s.length -1;
for(var i=0; i < l; i++){
if(s[i] != s[len - i]){
f = false;
break;
}
}
return f;
}
console.log(palindrom(12321));
Here's another way of doing it:
function isPalin(str) {
str = str.replace(/\W/g,'').toLowerCase();
return(str==str.split('').reverse().join(''));
}
Below code tells how to get a string from textBox and tell you whether it is a palindrome are not & displays your answer in another textbox
<html>
<head>
<meta charset="UTF-8"/>
<link rel="stylesheet" href=""/>
</head>
<body>
<h1>1234</h1>
<div id="demo">Example</div>
<a accessKey="x" href="http://www.google.com" id="com" >GooGle</a>
<h1 id="tar">"This is a Example Text..."</h1>
Number1 : <input type="text" name="txtname" id="numb"/>
Number2 : <input type="text" name="txtname2" id="numb2"/>
Number2 : <input type="text" name="txtname3" id="numb3" />
<button type="submit" id="sum" onclick="myfun()" >count</button>
<button type="button" id="so2" onclick="div()" >counnt</button><br/><br/>
<ol>
<li>water</li>
<li>Mazaa</li>
</ol><br/><br/>
<button onclick="myfun()">TryMe</button>
<script>
function myfun(){
var pass = document.getElementById("numb").value;
var rev = pass.split("").reverse().join("");
var text = document.getElementById("numb3");
text.value = rev;
if(pass === rev){
alert(pass + " is a Palindrome");
}else{
alert(pass + " is Not a Palindrome")
}
}
</script>
</body>
</html>
25x faster + recursive + non-branching + terse
function isPalindrome(s,i) {
return (i=i||0)<0||i>=s.length>>1||s[i]==s[s.length-1-i]&&isPalindrome(s,++i);
}
See my complete explanation here.
The code is concise quick fast and understandable.
TL;DR
Explanation :
Here isPalindrome function accepts a str parameter which is typeof string.
If the length of the str param is less than or equal to one it simply returns "false".
If the above case is false then it moves on to the second if statement and checks that if the character at 0 position of the string is same as character at the last place. It does an inequality test between the both.
str.charAt(0) // gives us the value of character in string at position 0
str.slice(-1) // gives us the value of last character in the string.
If the inequality result is true then it goes ahead and returns false.
If result from the previous statement is false then it recursively calls the isPalindrome(str) function over and over again until the final result.
function isPalindrome(str){
if (str.length <= 1) return true;
if (str.charAt(0) != str.slice(-1)) return false;
return isPalindrome(str.substring(1,str.length-1));
};
document.getElementById('submit').addEventListener('click',function(){
var str = prompt('whats the string?');
alert(isPalindrome(str))
});
document.getElementById('ispdrm').onsubmit = function(){alert(isPalindrome(document.getElementById('inputTxt').value));
}
<!DOCTYPE html>
<html>
<body>
<form id='ispdrm'><input type="text" id="inputTxt"></form>
<button id="submit">Click me</button>
</body>
</html>
function palindrome(str) {
var re = /[^A-Za-z0-9]/g;
str = str.toLowerCase().replace(re, '');
var len = str.length;
for (var i = 0; i < len/2; i++) {
if (str[i] !== str[len - 1 - i]) {
return false;
}
}
return true;
}
Or you could do it like this.
var palindrome = word => word == word.split('').reverse().join('')
How about this one?
function pall (word) {
var lowerCWord = word.toLowerCase();
var rev = lowerCWord.split('').reverse().join('');
return rev.startsWith(lowerCWord);
}
pall('Madam');
str1 is the original string with deleted non-alphanumeric characters and spaces and str2 is the original string reversed.
function palindrome(str) {
var str1 = str.toLowerCase().replace(/\s/g, '').replace(
/[^a-zA-Z 0-9]/gi, "");
var str2 = str.toLowerCase().replace(/\s/g, '').replace(
/[^a-zA-Z 0-9]/gi, "").split("").reverse().join("");
if (str1 === str2) {
return true;
}
return false;
}
palindrome("almostomla");
function isPalindrome(s) {
return s == reverseString(s);
}
console.log((isPalindrome("abcba")));
function reverseString(str){
let finalStr=""
for(let i=str.length-1;i>=0;i--){
finalStr += str[i]
}
return finalStr
}
Frist I valid this word with converting lowercase and removing whitespace and then compare with reverse word within parameter word.
function isPalindrome(input) {
const toValid = input.trim("").toLowerCase();
const reverseWord = toValid.split("").reverse().join("");
return reverseWord == input.toLowerCase().trim() ? true : false;
}
isPalindrome(" madam ");
//true
This answer is easy to read and I tried to explain by using comment. Check the code below for How to write Palindrome in JavaScript.
Step 1: Remove all non-alphanumeric characters (punctuation, spaces and symbols) from Argument string 'str' using replace() and then convert in to lowercase using toLowerCase().
Step 2: Now make string reverse. first split the string into the array using split() then reverse the array using reverse() then make the string by joining array elements using join() .
Step 3: Find the first character of nonAlphaNumeric string using charAt(0).
Step 4: Find the Last character of nonAlphaNumeric string using charAt(length of nonAlphaNumeric string - 1).
Step 5: Use If condition to chack nonAlphaNumeric string and reverse string is same or not.
Step 6: Use another If condition to chack first character of nonAlphaNumeric string is same to Last character of nonAlphaNumeric string.
function palindrome(str) {
var nonAlphaNumericStr = str.replace(/[^0-9A-Za-z]/g, "").toLowerCase(); // output - e1y1e
var reverseStr = nonAlphaNumericStr.split("").reverse().join(""); // output - e1y1e
var firstChar = nonAlphaNumericStr.charAt(0); // output - e
var lastChar = nonAlphaNumericStr.charAt(nonAlphaNumericStr.length - 1); // output - e
if(nonAlphaNumericStr === reverseStr) {
if(firstChar === lastChar) {
return `String is Palindrome`;
}
}
return `String is not Palindrome`;
}
console.log(palindrome("_eye"));
function check(txt)
{
for (var i = txt.length; i >= 0; i--)
if (txt[i] !== txt[txt.length - 1 - i])
return console.log('not palidrome');
return console.log(' palidrome');
}
check('madam');
Note: This is case sensitive
function palindrome(word)
{
for(var i=0;i<word.length/2;i++)
if(word.charAt(i)!=word.charAt(word.length-(i+1)))
return word+" is Not a Palindrome";
return word+" is Palindrome";
}
Here is the fiddle: http://jsfiddle.net/eJx4v/
I am not sure how this JSPerf check the code performance. I just tried to reverse the string & check the values. Please comment about the Pros & Cons of this method.
function palindrome(str) {
var re = str.split(''),
reArr = re.slice(0).reverse();
for (a = 0; a < re.length; a++) {
if (re[a] == reArr[a]) {
return false;
} else {
return true;
}
}
}
JS Perf test
In Perl I can repeat a character multiple times using the syntax:
$a = "a" x 10; // results in "aaaaaaaaaa"
Is there a simple way to accomplish this in Javascript? I can obviously use a function, but I was wondering if there was any built in approach, or some other clever technique.
These days, the repeat string method is implemented almost everywhere. (It is not in Internet Explorer.) So unless you need to support older browsers, you can simply write:
"a".repeat(10)
Before repeat, we used this hack:
Array(11).join("a") // create string with 10 a's: "aaaaaaaaaa"
(Note that an array of length 11 gets you only 10 "a"s, since Array.join puts the argument between the array elements.)
Simon also points out that according to this benchmark, it appears that it's faster in Safari and Chrome (but not Firefox) to repeat a character multiple times by simply appending using a for loop (although a bit less concise).
In a new ES6 harmony, you will have native way for doing this with repeat. Also ES6 right now only experimental, this feature is already available in Edge, FF, Chrome and Safari
"abc".repeat(3) // "abcabcabc"
And surely if repeat function is not available you can use old-good Array(n + 1).join("abc")
Convenient if you repeat yourself a lot:
String.prototype.repeat = String.prototype.repeat || function(n){
n= n || 1;
return Array(n+1).join(this);
}
alert( 'Are we there yet?\nNo.\n'.repeat(10) )
Array(10).fill('a').join('')
Although the most voted answer is a bit more compact, with this approach you don't have to add an extra array item.
An alternative is:
for(var word = ''; word.length < 10; word += 'a'){}
If you need to repeat multiple chars, multiply your conditional:
for(var word = ''; word.length < 10 * 3; word += 'foo'){}
NOTE: You do not have to overshoot by 1 as with word = Array(11).join('a')
The most performance-wice way is https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat
Short version is below.
String.prototype.repeat = function(count) {
if (count < 1) return '';
var result = '', pattern = this.valueOf();
while (count > 1) {
if (count & 1) result += pattern;
count >>>= 1, pattern += pattern;
}
return result + pattern;
};
var a = "a";
console.debug(a.repeat(10));
Polyfill from Mozilla:
if (!String.prototype.repeat) {
String.prototype.repeat = function(count) {
'use strict';
if (this == null) {
throw new TypeError('can\'t convert ' + this + ' to object');
}
var str = '' + this;
count = +count;
if (count != count) {
count = 0;
}
if (count < 0) {
throw new RangeError('repeat count must be non-negative');
}
if (count == Infinity) {
throw new RangeError('repeat count must be less than infinity');
}
count = Math.floor(count);
if (str.length == 0 || count == 0) {
return '';
}
// Ensuring count is a 31-bit integer allows us to heavily optimize the
// main part. But anyway, most current (August 2014) browsers can't handle
// strings 1 << 28 chars or longer, so:
if (str.length * count >= 1 << 28) {
throw new RangeError('repeat count must not overflow maximum string size');
}
var rpt = '';
for (;;) {
if ((count & 1) == 1) {
rpt += str;
}
count >>>= 1;
if (count == 0) {
break;
}
str += str;
}
// Could we try:
// return Array(count + 1).join(this);
return rpt;
}
}
If you're not opposed to including a library in your project, lodash has a repeat function.
_.repeat('*', 3);
// ā '***
https://lodash.com/docs#repeat
For all browsers
The following function will perform a lot faster than the option suggested in the accepted answer:
var repeat = function(str, count) {
var array = [];
for(var i = 0; i < count;)
array[i++] = str;
return array.join('');
}
You'd use it like this :
var repeatedString = repeat("a", 10);
To compare the performance of this function with that of the option proposed in the accepted answer, see this Fiddle and this Fiddle for benchmarks.
For moderns browsers only
In modern browsers, you can now do this using String.prototype.repeat method:
var repeatedString = "a".repeat(10);
Read more about this method on MDN.
This option is even faster. Unfortunately, it doesn't work in any version of Internet explorer. The numbers in the table specify the first browser version that fully supports the method:
In ES2015/ES6 you can use "*".repeat(n)
So just add this to your projects, and your are good to go.
String.prototype.repeat = String.prototype.repeat ||
function(n) {
if (n < 0) throw new RangeError("invalid count value");
if (n == 0) return "";
return new Array(n + 1).join(this.toString())
};
String.repeat() is supported by 96.39% of browsers as of now.
function pad(text, maxLength){
return text + "0".repeat(maxLength - text.length);
}
console.log(pad('text', 7)); //text000
/**
* Repeat a string `n`-times (recursive)
* #param {String} s - The string you want to repeat.
* #param {Number} n - The times to repeat the string.
* #param {String} d - A delimiter between each string.
*/
var repeat = function (s, n, d) {
return --n ? s + (d || "") + repeat(s, n, d) : "" + s;
};
var foo = "foo";
console.log(
"%s\n%s\n%s\n%s",
repeat(foo), // "foo"
repeat(foo, 2), // "foofoo"
repeat(foo, "2"), // "foofoo"
repeat(foo, 2, "-") // "foo-foo"
);
Just for the fun of it, here is another way by using the toFixed(), used to format floating point numbers.
By doing
(0).toFixed(2)
(0).toFixed(3)
(0).toFixed(4)
we get
0.00
0.000
0.0000
If the first two characters 0. are deleted, we can use this repeating pattern to generate any repetition.
function repeat(str, nTimes) {
return (0).toFixed(nTimes).substr(2).replaceAll('0', str);
}
console.info(repeat('3', 5));
console.info(repeat('hello ', 4));
Another interesting way to quickly repeat n character is to use idea from quick exponentiation algorithm:
var repeatString = function(string, n) {
var result = '', i;
for (i = 1; i <= n; i *= 2) {
if ((n & i) === i) {
result += string;
}
string = string + string;
}
return result;
};
For repeat a value in my projects i use repeat
For example:
var n = 6;
for (i = 0; i < n; i++) {
console.log("#".repeat(i+1))
}
but be careful because this method has been added to the ECMAScript 6 specification.
function repeatString(n, string) {
var repeat = [];
repeat.length = n + 1;
return repeat.join(string);
}
repeatString(3,'x'); // => xxx
repeatString(10,'š¹'); // => "š¹š¹š¹š¹š¹š¹š¹š¹š¹š¹"
This is how you can call a function and get the result by the helps of Array() and join()
using Typescript and arrow fun
const repeatString = (str: string, num: number) => num > 0 ?
Array(num+1).join(str) : "";
console.log(repeatString("š·",10))
//outputs: š·š·š·š·š·š·š·š·š·š·
function repeatString(str, num) {
// Array(num+1) is the string you want to repeat and the times to repeat the string
return num > 0 ? Array(num+1).join(str) : "";
}
console.log(repeatString("a",10))
// outputs: aaaaaaaaaa
console.log(repeatString("š·",10))
//outputs: š·š·š·š·š·š·š·š·š·š·
Here is what I use:
function repeat(str, num) {
var holder = [];
for(var i=0; i<num; i++) {
holder.push(str);
}
return holder.join('');
}
I realize that it's not a popular task, what if you need to repeat your string not an integer number of times?
It's possible with repeat() and slice(), here's how:
String.prototype.fracRepeat = function(n){
if(n < 0) n = 0;
var n_int = ~~n; // amount of whole times to repeat
var n_frac = n - n_int; // amount of fraction times (e.g., 0.5)
var frac_length = ~~(n_frac * this.length); // length in characters of fraction part, floored
return this.repeat(n) + this.slice(0, frac_length);
}
And below a shortened version:
String.prototype.fracRepeat = function(n){
if(n < 0) n = 0;
return this.repeat(n) + this.slice(0, ~~((n - ~~n) * this.length));
}
var s = "abcd";
console.log(s.fracRepeat(2.5))
I'm going to expand on #bonbon's answer. His method is an easy way to "append N chars to an existing string", just in case anyone needs to do that. For example since "a google" is a 1 followed by 100 zeros.
for(var google = '1'; google.length < 1 + 100; google += '0'){}
document.getElementById('el').innerText = google;
<div>This is "a google":</div>
<div id="el"></div>
NOTE: You do have to add the length of the original string to the conditional.
Lodash offers a similar functionality as the Javascript repeat() function which is not available in all browers. It is called _.repeat and available since version 3.0.0:
_.repeat('a', 10);
var stringRepeat = function(string, val) {
var newString = [];
for(var i = 0; i < val; i++) {
newString.push(string);
}
return newString.join('');
}
var repeatedString = stringRepeat("a", 1);
Can be used as a one-liner too:
function repeat(str, len) {
while (str.length < len) str += str.substr(0, len-str.length);
return str;
}
In CoffeeScript:
( 'a' for dot in [0..10]).join('')
String.prototype.repeat = function (n) { n = Math.abs(n) || 1; return Array(n + 1).join(this || ''); };
// console.log("0".repeat(3) , "0".repeat(-3))
// return: "000" "000"