My problem is simple but I can't find a way to make thag work
The idea is that if a variable (number) mets a condittion defined on another variable (cond), run some code
Example:
var cond = '> 4';
var number = 5;
// Some type of if statement to check if 5 is > 4
You can use eval but usually if you resort to eval, you're not understanding the problem correctly.
var cond = '> 4';
var number = 5;
if (eval(number + cond)) {
console.log(number + cond);
}
Another possibility would be to create functions which correlate with the condition then store the operand in another variable.
var compareFunctions = {
'>': function(a, b) {
return a > b;
}
};
var op = '>';
var operand = 4;
var number = 5;
if (compareFunctions[op](number, operand)) {
console.log(number + op + operand);
}
Do you mean like this?
if (eval(number+cond)){
console.log("success");
}
You could use a function for the check of the condition.
var cond = function (x) { return x > 4; };
var number = 5;
console.log(cond(number));
The simple, but likely dangerous and ugly way would be to use eval()
var cond = '> 5';
console.log(eval(4 + cond));
console.log(eval(6 + cond));
However, this is dangerous because if that string is in any way coming from the user, they could enter bad things and make bad things happen.
A more proper way to handle it would be to parse it properly:
let cond = '> 5';
const evaluateCondition = (value, condition) => {
// Allows for >, <, >=, <=, !=, ==
let [, operator, operand] = condition.match(/^\s*(>|<|>=|<=|!=|==)\s*(\d+)$/);
switch(operator) {
case '>':
return value > operand;
case '<':
return value < operand;
case '==':
return value == operand;
// ... implement other operators here
}
};
console.log(evaluateCondition(4, cond));
console.log(evaluateCondition(6, cond));
This will let you define valid operators and handle them in a safe manner, also easily catching invalid input.
Below was done before an edit changed the question.
You have to declare the variable outside of it, but you can set it pretty easily. The syntax I would use looks like this:
var a = 5, b;
a == 5 && (b = 2);
The bit after the && only executes if the first condition is true. To set a variable in a syntax like this, you just wrap it in parentheses.
The more traditional way would be to use an if statement:
var a = 5, b;
if (a == 5) {
b = 2;
}
If you declare the second variable inside of the if statement, it doesn't exist outside of it:
var a = 5;
if (a == 5) {
var b = 2;
}
console.log(b) // undefined
which might be what was tripping you up.
You could use eval just be careful and make sure you read up on eval first:
var cond = '> 4';
var number = 5;
console.log(eval(("" + number + cond)));
Related
I'm writing a function that will return true or false in regards to whether or not the input string is in alphabetical order. I'm getting undefined and not sure what I'm missing
function is_alphabetic(str) {
let result = true;
for (let count = 1, other_count = 2; count >= str.length - 1, other_count >= str.length; count++,
other_count++) {
if (str.at[count] > str.at[other_count]) {
let result = false
}
return result
}
}
console.log(is_alphabetic('abc'));
you have put return statement inside the for loop, it should be outside the loop body.
Your code is also not correct. count should start from 0, other_count should start from 1.
count >= str.length - 1 should be count < str.length - 1 (this condition is completely unnecessary in your code because other_count < str.length should be the terminating condition in the loop)
and
other_count >= str.length should be other_count < str.length
Here's your corrected code
function is_alphabetic(str) {
let result = true;
for (let count = 0, other_count = 1; other_count < str.length; count++, other_count++) {
if (str[count] > str[other_count]) {
result = false
}
}
return result;
}
console.log(is_alphabetic('abc'));
Here's an alternative approach
function is_alphabetic(str){
return str.split('')
.every((c, idx) => str[idx + 1] ? c < str[idx + 1] : true);
}
console.log(is_alphabetic('abc'));
Keep in mind that if you want the comparisons between the characters to be case-insensitive, then convert the string in to lowercase before comparing the characters.
I think is easier if you compare the string using this function:
var sortAlphabets = function(text) {
return text.split('').sort().join('');
};
This produces results like:
sortAlphabets("abghi")
output: "abghi"
Or:
sortAlphabets("ibvjpqjk")
output: "bijjkpqv"
if you want to know if your string is alphabetically sorted, you might use:
var myString = "abcezxy"
sortAlphabets(myString) == myString
output: false
Or in case, you want to create an specific function:
function isSorted(myString) {
return sortAlphabets(myString) == myString
}
And for that case, you can use:
isSorted("abc")
var sortAlphabets = function(text) {
return text.split('').sort().join('');
};
function isSorted(myString) {
return sortAlphabets(myString) == myString
}
alert("is abc sorted: " + isSorted("abc"));
alert("is axb sorted: " + isSorted("axb"));
This should do it. I used .localeCompare() as this will ignore small/capital differences and will also deal reasonably with language specific characters, like German Umlauts.
function is_alphabetic(str){
return !str.split('').some((v,i,a)=>i&&v.localeCompare(a[i-1])<0)
}
['abcdefg','aacccRt','ashhe','xyz','aüv'].forEach(s=> console.log(s,is_alphabetic(s)) );
There are two issues in your code:
Your return statement is in your for-loop. To avoid such mistakes you can get a code-formatter like prettier;
Your for-loop condition is invalid. Keep in mind that the second part of the for-loop statement is supposed to be true to do an iteration and false to stop doing iterations. In this case, your condition count >= str.length-1, other_count >= str.length will first evaluate count >= str.length-1, discard the result because of the comma operator, evaluate other_count >= str.length which immediately resolves to false.
These two things together make it so your function never returns, which the javascript runtime interprets as undefined.
Hope this helps you understand what went wrong. But like many other pointed out, there are better ways to tackle the problem you're trying to solve.
You just have to compare the string with its corresponding 'sorted' one
let string = 'abc'.split('').join('');
let sortedString = 'abc'.split('').sort().join('');
console.log(sortedString === sortedString)
let string2 = 'dbc'.split('').join('');
let sortedString2 = 'dbc'.split('').sort().join('');
console.log(string2 === sortedString2)
I have a code but it is not working for operator precedence. It is normally executing from first to last operator entered in a string.
It gives correct answer while string follow precedence rule(eg."12 * 10 / 5 + 10 - 1" = 33 <- correct answer). But it gives wrong answer while string doesn't follow precedence rule(eg. "15 + 10 * 5 / 10 - 1" = 49 <- wrong answer. actual answer is 19)
code:
var str="12 * 10 / 5 + 10 - 1";
var res=[],n1=[],num=[],op=[],o1=[];
var result;
res= str.split(" ");
console.error("res",res);
document.write(res.join(",")+"<br>");
for(var i=0;i<res.length;i++)
{
if(i%2==0)
{
num.push(parseInt(res[i]));
}
else
{
op.push(res[i]);
}
}
document.write(num+"<br>");
document.write(op+"<br>");
var myFunction = function(num1,num2,oper){
var j;
if(oper=='-'){
j = num1-num2;
return j;
}else if(oper=='+'){
j = num1+num2;
return j;
}else if(oper=='*'){
j = num1*num2;
return j;
}else if(oper=='/'){
j = num1/num2;
return j;
}else{
j = 0;
return j;
}
}
var x=num[0];
for(var i=1; i<num.length; i++){
x = myFunction(x,num[i],op[i-1]);
}
document.write("result of "+str+" is "+x+"<br>");
Here's one way to do it. I like because this is how we craft a parser. There are other approaches as mentioned, usual when you're using a parser generator like lex/yacc.
As you have noticed, there are times we need to save an intermediate result in order to process another part of an expression. This way, called a recursive descent parser, uses the environment's own stack to save the temp results. Another way is to use maintain a stack yourself, but that's not much valuable.
This is also very flexible. It's pretty easy to extend the grammar to different precedence levels. Change parseFactor below to parse negation and parentheses.
function parse(expression) {
return expression.split(' ')
}
function consumeNumber(tokens) {
const token = tokens.shift()
return parseInt(token)
}
function consumeOp(tokens, allowed) {
const token = tokens[0]
if (allowed.indexOf(token) >= 0) {
tokens.shift()
return token
}
}
function parseFactor(tokens) {
return consumeNumber(tokens)
}
function parseTerm(tokens) {
let value = parseFactor(tokens)
let op
while (op = consumeOp(tokens, ['*', '/'])) {
let nextVal = parseFactor(tokens)
switch (op) {
case '*':
value *= nextVal
break
case '/':
value /= nextVal
break
}
}
return value
}
function parseExpression(tokens) {
let value = parseTerm(tokens)
let op
while (op = consumeOp(tokens, ['+', '-'])) {
let nextVal = parseTerm(tokens)
switch (op) {
case '+':
value += nextVal
break
case '-':
value -= nextVal
break
}
}
return value
}
function evaluate(expression) {
const tokens = parse(expression)
return parseExpression(tokens)
}
evaluate('15 + 10 * 5 / 10 - 1')
Here's a hacked together (read: shouldn't actually be used anywhere real without extra work / error checking) object which gets the correct answer for both test cases. I'm sure this could be improved on and there's likely better algorithms for this. As per my comment it just scans for * or / and processes that calculation, then generates a new number/operator set including that result. I mainly just wrote it for fun.
I haven't bothered with the code to try and parse the string, this just takes an array of numbers and an array of operators.
(Also I get 11.5 as the incorrect result for your second test, both manually and running your code)
<script>
myCalc = {
getResult: function(n, o){
this.numbers = n;
this.operators = o;
// keep going until our list of numbers is just the final result
while( this.numbers.length > 1 )
this.findNext();
return this.numbers[0];
},
findNext: function(){
var opIndex = 0;
// find the next * or / operator
for(i=0;i<=this.operators.length;i++){
if( this.operators[i] == '*' || this.operators[i] == '/' ){
opIndex = i;
break;
}
}
var opResult = this.doCalc(this.operators[opIndex], this.numbers[opIndex], this.numbers[opIndex+1]);
// update our main numbers list and splice out the operator we just processed
// replace "x" with the result, and splice "y"
this.numbers[opIndex] = opResult;
this.numbers.splice(opIndex + 1, 1);
this.operators.splice(opIndex, 1);
console.log(this.numbers);
console.log(this.operators);
},
doCalc: function(op,x,y){
switch(op){
case '*':
return x * y;
case '/':
return x / y;
case '+':
return x + y;
case '-':
return x - y;
}
return 0;
}
};
console.log(myCalc.getResult([15,10,5,10,1], ['+','*','/','-']));
console.log(myCalc.getResult([12,10,5,10,1], ['*','/','+','-']));
</script>
Since nobody mentioned it before, you could simply process your string with eval function:
var str="15 + 10 * 5 / 10 - 1";
console.log(eval(str));
// logs 19
If the argument is an expression, eval() evaluates the expression
Is it possible to make an operator type of string into operator
<script>
var operator = $(this).val(); returns a string eg) + or -
var quantity = 5 operator 1;
</script>
currently i am using switch
It's possible, in a way, via eval, but see caveats. Example:
var result = eval("5 " + operator + " 1"); // 6 if operator is +
The problem with eval is that it's a full JavaScript evaluator, and so you have to be really sure that the content is under your control. User-contributed content, for instance, is something you have to be very, very cautious with.
Alternately, just do a switch:
switch (operator) {
case "+":
result = 5 + 1;
break;
case "-":
result = 5 - 1;
break;
case "/":
result = 5 / 1;
break;
case "*":
result = 5 * 1;
break;
// ...and so on, for your supported operators
}
The absolutely most simple way would be to use a if:
var operator = $(this).val(); // returns a string eg) + or -
var quantity;
if(operator === '-') {
quantity = 5 - 1;
} else if(operator === '+') {
quantity = 5 + 1;
}
You could also use the eval function, but eval is very rarely recommended and is not really worth it in a case like this.
No. The easiest would be to use eval:
var quantity = eval("5 " + operator + " 1");
but it is considered a bad practice. Eval is Evil. Not only do you have security concerns, it also slows down the execution of your code.
Rather, this approach is much better and safer:
var operators = {
"+": function(a, b) { return a + b; };
"-": function(a, b) { return a - b; };
};
var operatorFunction = operators[operator];
if (operatorFunction) {
var quantity = operatorFunction(5, 1);
}
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
I am creating a program in javascript and I don't know how I can achieve following; My program takes argument such as "+","-" and other mathematical operators as string which I want to convert to real operators. For example (Pseudo-code):
function calc(a,b,c, op1,op2){
output=(a op1 b op2 c)
}
calc(2,3,4,"+","-")
Output should be now = 2+3-4.
However, I don't know in advance how many operators I will have and also the numbers. In other words, my objective is to replace 1,"+",2, "-",4,"+","(",5,"+",6,")".........and so on with 1+2-4+(5+6).....
How can I implement this in a nice manner?
Well, you could use eval but you can do simply this :
var funcs = {
'+': function(a,b){ return a+b },
'-': function(a,b){ return a-b }
};
function calc(a,b,c, op1,op2){
return funcs[op2](funcs[op1](a, b), c);
}
You can easily extend the funcs map with other operators.
I really would suggest using eval for this particular case:
eval("var res = " + 1 + "+" + 2 + "-" + 4 + "+" + "(" + 5 + "+" + 6 + ")");
console.log(res); //10
I know, I know, everone says you should avoid eval where possible. And they are right. eval has great power and you should only use it with great responsibility, in particular when you evaluate something, that was entered by the end user. But if you are careful, you can use eval and be fine.
This has been done very quickly, but should do the trick(JSFiddle here):
function executeMath() {
if (arguments.length % 2 === 0) return null;
var initialLength = arguments.length,
numberIndex = (initialLength + 1)/2,
numbers = Array.prototype.splice.call(arguments, 0, numberIndex),
operands = Array.prototype.splice.call(arguments, 0),
joiner = new Array(arguments.length);
for (var i = 0; i < numbers.length; i++) {
joiner[i*2] = numbers[i];
}
for (var i = 0; i < operands.length; i++) {
joiner[1+(i*2)] = operands[i];
}
var command = ("return (" + joiner.join('') + ");"),
execute = new Function(command);
console.log(command);
return execute();
}
console.log(executeMath(2, 3, 4, 5, "/", "+", "%"));