100

JavaScript has parseInt() and parseFloat(), but there's no parseBool or parseBoolean method in the global scope, as far as I'm aware.

I need a method that takes strings with values like "true" or "false" and returns a JavaScript Boolean.

Here's my implementation:

function parseBool(value) {
    return (typeof value === "undefined") ? 
           false : 
           // trim using jQuery.trim()'s source 
           value.replace(/^\s+|\s+$/g, "").toLowerCase() === "true";
}

Is this a good function? Please give me your feedback.

Thanks!

2

14 Answers 14

108

I would be inclined to do a one liner with a ternary if.

var bool_value = value == "true" ? true : false

Edit: Even quicker would be to simply avoid using the a logical statement and instead just use the expression itself:

var bool_value = value == 'true';

This works because value == 'true' is evaluated based on whether the value variable is a string of 'true'. If it is, that whole expression becomes true and if not, it becomes false, then that result gets assigned to bool_value after evaluation.

Sign up to request clarification or add additional context in comments.

10 Comments

Why not shorten it a bit further? var bool_value = value == "true" does the same thing :)
A ternary expression could be useful here, to handle the case where you're passed null/undefined/empty: bool_value = value ? (value.toLowerCase() == "true") : false
Shorter way: var bool = !!value
@Ifch0o1 I wouldn't use var bool = !!value. The string containing "false" is a truthy value so !!'false' === true
I typically expect that when someone says they want to "parse a string into a boolean" they mean that they want to map the string "false" to the boolean value false. However in javascript, !!'false' yields the boolean value true. If you don't believe me, open the javascript console in your favorite browser or a nodeJS repl and try it yourself. If the original poster is ok with this "parsing" taking "false" to true then I suppose !! is just fine, but that's certainly not the behavior I'd expect from a parser.
|
99

You can use JSON.parse for that:

JSON.parse("true"); //returns boolean true

3 Comments

Doesn't handle mixed case JSON.parse("True") or non-JSON syntax e.g. JSON.parse("x")
This needs to be the accepted answer
@AndrewL you could potentially do JSON.parse("True".toLowerCase()) replacing "True" with your variable
18

It depends how you wish the function to work.

If all you wish to do is test for the word 'true' inside the string, and define any string (or nonstring) that doesn't have it as false, the easiest way is probably this:

function parseBoolean(str) {
  return /true/i.test(str);
}

If you wish to assure that the entire string is the word true you could do this:

function parseBoolean(str) {
  return /^true$/i.test(str);
}

3 Comments

The way this natively works is absolutely stupid. The Boolean function should do the latter of your examples. If one needs to see if a string contains the word true or false then you should check if the index is > 0.
This has a huge amount of overhead matching with regex, instead of simply checking if the string contains 'true' or not.
@Soviut: quite right, RGBs solution is much prfered
11

You can try the following:

function parseBool(val)
{
    if ((typeof val === 'string' && (val.toLowerCase() === 'true' || val.toLowerCase() === 'yes')) || val === 1)
        return true;
    else if ((typeof val === 'string' && (val.toLowerCase() === 'false' || val.toLowerCase() === 'no')) || val === 0)
        return false;

    return null;
}

If it's a valid value, it returns the equivalent bool value otherwise it returns null.

2 Comments

This almost worked, I tweaked it a bit to get it to work properly (single quotes around 'string'): function parseBool(val) { if ((typeof val == 'string' && (val.toLowerCase() === 'true' || val.toLowerCase() === 'yes')) || val === 1) return true; else if ((typeof val === 'string' && (val.toLowerCase() === 'false' || val.toLowerCase() === 'no')) || val === 0) return false; return null; }
@delliottg Updated with quotes on string.
4

You can use JSON.parse or jQuery.parseJSON and see if it returns true using something like this:

function test (input) {
    try {
        return !!$.parseJSON(input.toLowerCase());
    } catch (e) { }
}

5 Comments

Looks a bit dangerous to me. For example, test("\"false\"") will return true for being a non-empty string. It's unlikely, but a very unobvious source for bugs.
If the input is invalid JSON, this function will return undefined.
@idealmaschine: Which seems to be a Good Thing to me. Is that what you wanted to say, or was that a criticism?
@RoToRa: Good point. But not knowing the data it's hard to know if "\"false\"" should be true or false – and what about "\"not true\"" or "\"no\"" or "yes"? One possibility would be to return undefined for everything other than explicit true or false, or use the usual JavaScript or JSON semantics, or use some custom logic that is suitable for a given application. It's hard to make a universal solution if it is even hard to find two programming languages that would agree on what is true and what is false.
@idealmaschine: You can add return false; in the catch block if you want to get false for invalid JSON, but keep in mind that undefined is also falsy in JavaScript so it may not really matter, depending on how you use it.
4

last but not least, a simple and efficient way to do it with a default value :

ES5

function parseBool(value, defaultValue) {
    return (value == 'true' || value == 'false' || value === true || value === false) && JSON.parse(value) || defaultValue;
}

ES6 , a shorter one liner

const parseBool = (value, defaultValue) => ['true', 'false', true, false].includes(value) && JSON.parse(value) || defaultValue

JSON.parse is efficient to parse booleans

Comments

3

Personally I think it's not good, that your function "hides" invalid values as false and - depending on your use cases - doesn't return true for "1".

Another problem could be that it barfs on anything that's not a string.

I would use something like this:

function parseBool(value) {
  if (typeof value === "string") {
     value = value.replace(/^\s+|\s+$/g, "").toLowerCase();
     if (value === "true" || value === "false")
       return value === "true";
  }
  return; // returns undefined
}

And depending on the use cases extend it to distinguish between "0" and "1".

(Maybe there is a way to compare only once against "true", but I couldn't think of something right now.)

3 Comments

Sorry to dredge up really old code, but why not just return true;? why return value === "true";? I mean, you already checked if it's valid, right?
@Metagrapher If I just return true, it will return true, if the value is "false", too.
I don't know what was wrong with me when I read that code. Sorry. haha thanks for the clarity.
3

Why not keep it simple?

var parseBool = function(str) {
    if (typeof str === 'string' && str.toLowerCase() == 'true')
            return true;

    return (parseInt(str) > 0);
}

Comments

3

You can add this code:

function parseBool(str) {
  
  if (str.length == null) {
    return str == 1;
  } else {
    return str == "true";
  }
 
}

Works like this:

parseBool(1) //true
parseBool(0) //false
parseBool("true") //true
parseBool("false") //false

1 Comment

I see ternarys used a lot like this but they aren't needed. You can just do return (str === 1)
2

Wood-eye be careful. After looking at all this code, I feel obligated to post:

Let's start with the shortest, but very strict way:

var str = "true";
var mybool = JSON.parse(str);

And end with a proper, more tolerant way:

var parseBool = function(str) 
{
    // console.log(typeof str);
    // strict: JSON.parse(str)

    if(str == null)
        return false;

    if (typeof str === 'boolean')
    {
        if(str === true)
            return true;

        return false;
    } 

    if(typeof str === 'string')
    {
        if(str == "")
            return false;

        str = str.replace(/^\s+|\s+$/g, '');
        if(str.toLowerCase() == 'true' || str.toLowerCase() == 'yes')
            return true;

        str = str.replace(/,/g, '.');
        str = str.replace(/^\s*\-\s*/g, '-');
    }

    // var isNum = string.match(/^[0-9]+$/) != null;
    // var isNum = /^\d+$/.test(str);
    if(!isNaN(str))
        return (parseFloat(str) != 0);

    return false;
}

Testing:

var array_1 = new Array(true, 1, "1",-1, "-1", " - 1", "true", "TrUe", "  true  ", "  TrUe", 1/0, "1.5", "1,5", 1.5, 5, -3, -0.1, 0.1, " - 0.1", Infinity, "Infinity", -Infinity, "-Infinity"," - Infinity", " yEs");

var array_2 = new Array(null, "", false, "false", "   false   ", " f alse", "FaLsE", 0, "00", "1/0", 0.0, "0.0", "0,0", "100a", "1 00", " 0 ", 0.0, "0.0", -0.0, "-0.0", " -1a ", "abc");


for(var i =0; i < array_1.length;++i){ console.log("array_1["+i+"] ("+array_1[i]+"): " + parseBool(array_1[i]));}

for(var i =0; i < array_2.length;++i){ console.log("array_2["+i+"] ("+array_2[i]+"): " + parseBool(array_2[i]));}

for(var i =0; i < array_1.length;++i){ console.log(parseBool(array_1[i]));}
for(var i =0; i < array_2.length;++i){ console.log(parseBool(array_2[i]));}

Comments

0

I like the solution provided by RoToRa (try to parse given value, if it has any boolean meaning, otherwise - don't). Nevertheless I'd like to provide small modification, to have it working more or less like Boolean.TryParse in C#, which supports out params. In JavaScript it can be implemented in the following manner:

var BoolHelpers = {
    tryParse: function (value) {
        if (typeof value == 'boolean' || value instanceof Boolean)
            return value;
        if (typeof value == 'string' || value instanceof String) {
            value = value.trim().toLowerCase();
            if (value === 'true' || value === 'false')
                return value === 'true';
        }
        return { error: true, msg: 'Parsing error. Given value has no boolean meaning.' }
    }
}

The usage:

var result = BoolHelpers.tryParse("false");
if (result.error) alert(result.msg);

Comments

0

I shamelessly converted Apache Common's toBoolean to JavaScript:

JSFiddle: https://jsfiddle.net/m2efvxLm/1/

Code:

function toBoolean(str) {
  if (str == "true") {
    return true;
  }
  if (!str) {
    return false;
  }
  switch (str.length) {
    case 1: {
      var ch0 = str.charAt(0);
      if (ch0 == 'y' || ch0 == 'Y' ||
          ch0 == 't' || ch0 == 'T' ||
          ch0 == '1') {
        return true;
      }
      if (ch0 == 'n' || ch0 == 'N' ||
          ch0 == 'f' || ch0 == 'F' ||
          ch0 == '0') {
        return false;
      }
      break;
    }
    case 2: {
      var ch0 = str.charAt(0);
      var ch1 = str.charAt(1);
      if ((ch0 == 'o' || ch0 == 'O') &&
          (ch1 == 'n' || ch1 == 'N') ) {
        return true;
      }
      if ((ch0 == 'n' || ch0 == 'N') &&
          (ch1 == 'o' || ch1 == 'O') ) {
        return false;
      }
      break;
    }
    case 3: {
      var ch0 = str.charAt(0);
      var ch1 = str.charAt(1);
      var ch2 = str.charAt(2);
      if ((ch0 == 'y' || ch0 == 'Y') &&
          (ch1 == 'e' || ch1 == 'E') &&
          (ch2 == 's' || ch2 == 'S') ) {
        return true;
      }
      if ((ch0 == 'o' || ch0 == 'O') &&
          (ch1 == 'f' || ch1 == 'F') &&
          (ch2 == 'f' || ch2 == 'F') ) {
        return false;
      }
      break;
    }
    case 4: {
      var ch0 = str.charAt(0);
      var ch1 = str.charAt(1);
      var ch2 = str.charAt(2);
      var ch3 = str.charAt(3);
      if ((ch0 == 't' || ch0 == 'T') &&
          (ch1 == 'r' || ch1 == 'R') &&
          (ch2 == 'u' || ch2 == 'U') &&
          (ch3 == 'e' || ch3 == 'E') ) {
        return true;
      }
      break;
    }
    case 5: {
      var ch0 = str.charAt(0);
      var ch1 = str.charAt(1);
      var ch2 = str.charAt(2);
      var ch3 = str.charAt(3);
      var ch4 = str.charAt(4);
      if ((ch0 == 'f' || ch0 == 'F') &&
          (ch1 == 'a' || ch1 == 'A') &&
          (ch2 == 'l' || ch2 == 'L') &&
          (ch3 == 's' || ch3 == 'S') &&
          (ch4 == 'e' || ch4 == 'E') ) {
        return false;
      }
      break;
    }
    default:
      break;
  }

  return false;
}
console.log(toBoolean("yEs")); // true
console.log(toBoolean("yES")); // true
console.log(toBoolean("no")); // false
console.log(toBoolean("NO")); // false
console.log(toBoolean("on")); // true
console.log(toBoolean("oFf")); // false
Inspect this element, and view the console output.

3 Comments

Seems absurd to me why they wouldn't include a case for: typeof === 'boolean', in case someone literally passes true or false.
There's no need, as Java is a strongly-typed language.
@XaeroDegreaz it's JavaScript, not Java. Aside from that, this example looks absurdly verbose and unnecessary
0

stringjs has a toBoolean() method:

https://www.npmjs.com/package/string#--toboolean--tobool

S('true').toBoolean() //true
S('false').toBoolean() //false
S('hello').toBoolean() //false
S(true).toBoolean() //true
S('on').toBoolean() //true
S('yes').toBoolean() //true
S('TRUE').toBoolean() //true
S('TrUe').toBoolean() //true
S('YES').toBoolean() //true
S('ON').toBoolean() //true
S('').toBoolean() //false
S(undefined).toBoolean() //false
S('undefined').toBoolean() //false
S(null).toBoolean() //false
S(false).toBoolean() //false
S({}).toBoolean() //false
S(1).toBoolean() //true
S(-1).toBoolean() //false
S(0).toBoolean() //false

2 Comments

The link leads to the landing page of a chinese web agency
Thanks, I've corrected the URL (linked to NPM now).
-7

Enough to using eval javascript function to convert string to boolean

eval('true')  
eval('false')

3 Comments

Eval breaks lots of optimizations, results in slow code, is hard to debug and bad to maintain. If you can, never use it - there are much better ways to solve this problem, see the other answers.
In this case, none of your listed is not critical and applicable.
Jens everything you mention doesn't apply in this case, but the actually important problem with this is not mentioned, security. eval can lead to js injection, so don't use it if you can't trust the input source, and if you're on a browser you can hardly trust in that ever. JSON.parse is the safe way (not sure if the fastest).

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.