Как превратить NaN из parseInt в 0 для пустой строки?


298

Можно ли как-то вернуть 0 вместо NaNразбора значений в JavaScript?

В случае пустой строки parseIntвозвращается NaN.

Можно ли сделать что-то подобное в JavaScript для проверки NaN?

var value = parseInt(tbb) == NaN ? 0 : parseInt(tbb)

Или, может быть, есть другая функция или плагин jQuery, который может сделать что-то подобное?


72
К вашему сведению NaN != NaN. Тебе нужно isNaN(value).
pimvdb

28
Да, две няни не одинаковы;)
Джеймс П.

3
Вызов функции parseInt()дважды (в успешном / обычном NaNслучае) никогда не является хорошей идеей. Помимо неэффективности, для неосторожного, если то, что передается для tbbвызова функции с побочными эффектами, это ужасно. Я не стал бы использовать какое-либо решение здесь, где я вижу parseInt()дважды.
JonBrave

Ответы:


756
var s = '';

var num = parseInt(s) || 0;

Когда не используется с логическими значениями, логический ||оператор OR ( ) возвращает первое выражение ( parseInt(s)), если оно может быть оценено как true, в противном случае он возвращает второе выражение (0). Возвращаемое значение parseInt('')NaN. NaN оценивается как ложное, поэтому в numконечном итоге устанавливается на 0.


6
Это не сработает, если s = "4s"; (возвращает 4 ... что неверно ...)
markzzz

1
Функция parseInt в js разбирает любые числа в строке
ali youhannaei

26
@markzzz Прочитайте вопрос снова. ОП спрашивает: « Можно ли как-нибудь вернуть 0 вместо NaN ». OP не хочет проверять, является ли конкретная строка доступной для int. ОП хочет получить 0вместо NaN. Это решается кодом Мэтта отлично.
Трейдер

2
@markzzzvar nextIphone = parseInt("4S") + 1; // wow it works!
Нулевое отвлечение

2
@ Матфея, пожалуйста, используйте термины "ложь" или "правдивый" . потому что NaN === ложь это ложь! но Boolean (NaN) === Boolean (false) - это правда. логическое ИЛИ возвращает первое выражение, если оно может быть оценено как «правдивое»
Pablo Recalde

52

Вы также можете использовать isNaN()функцию:

var s = ''
var num = isNaN(parseInt(s)) ? 0 : parseInt(s)

12
Зачем звонить parseInt(s)дважды? Кроме того, это должно бытьparseInt(s, 10)
Dexygen

2
@GeorgeJempty Основой по умолчанию является «10»; этот параметр не является обязательным. Хороший момент при звонке parseInt()дважды, хотя.
Осень Леонард

8
@AutumnLeonard это только вид правды. Если ваша строка начинается с 0, это предполагает, что число в восьмеричном формате, поэтому parseInt ('077') дает вам 63. Это может привести к очень неприятному поиску ошибок, поэтому вы всегда должны указывать второй параметр. смотри, например , stackoverflow.com/questions/8763396/...
chuck258

22

Я был удивлен, не увидев никого упоминания об использовании Number(). Конечно, он будет анализировать десятичные дроби, если он предоставлен, поэтому будет действовать иначе, чем parseInt(), однако, он уже предполагает основание 10 и превратит «или даже» в 0.


1
Да, очень удобно для чтения из localStorage: Number (localStorage.getItem ('appBanner.count')) + 1
Филипп Мерфи

Хотя это работает для вопроса, как он был задан, он все равно возвращает NaN для нечисловых непробельных символов
Кайл Делани

9

Для людей, которые не ограничены parseInt, вы можете использовать побитовый оператор ИЛИ (который неявно вызывает ToInt32его операнды).

var value = s | 0;

// NaN | 0     ==>> 0
// ''  | 0     ==>> 0
// '5' | 0     ==>> 5
// '33Ab' | 0  ==>> 0
// '0x23' | 0  ==>> 35
// 113 | 0     ==>> 113
// -12 | 0     ==>> -12
// 3.9 | 0     ==>> 3

Примечание: ToInt32отличается от parseInt. (то есть parseInt('33Ab') === 33)


Но: '10000000000' | 0 === 1410065408.
Trincot

@trincot да, любое значение> = Math.pow(2, 31)будет переполнено.
Ахмад Ибрагим

8

Эта проблема

Другие ответы не принимают во внимание, что 0это ложно, и, следовательно, следующее будет 20 вместо 0:

const myNumber = parseInt('0') || 20; // 20

Решение

Я предлагаю вспомогательную функцию, которая решает большинство проблем:

function getNumber({ value, defaultValue }) {
  const num = parseInt(value, 10);
  return isNaN(num) ? defaultValue : num;
}

Вспомогательная функция даст следующие результаты:

getNumber({ value: "0", defaultValue: 20 }); // 0
getNumber({ value: "2", defaultValue: 20 }); // 2
getNumber({ value: "2.2", defaultValue: 20 }); // 2
getNumber({ value: "any string", defaultValue: 20 }); // 20
getNumber({ value: undefined, defaultValue: 20 }); // 20
getNumber({ value: null, defaultValue: 20 }); // 20
getNumber({ value: NaN, defaultValue: 20 }); // 20
getNumber({ value: false, defaultValue: 20 }); // 20
getNumber({ value: true, defaultValue: 20 }); // 20

2
Пожалуйста, отправьте parseInt(string, radix)parseInt("0x10") === 16parseInt("010")8
основную ссылку

2
Если вы уже зависите от lodash для других вещей, есть удобная defaultToфункция, которая делает именно это: _.defaultTo(NaN, -1)возвращает -1, но_.defaultTo(0, -1); возвращает 0.
Вальдирий

Это отличный момент! Вы можете рассчитывать только на || в конце, чтобы обеспечить правильное значение по умолчанию, когда предпочитаемое значение по умолчанию - НОЛЬ (предоставлено, это то, что хотел ОП). Как вы уже упоминали, из-за ложной природы ввода '0' в этом случае он обрабатывается как недопустимый ввод, и вместо этого оператор возвращает значение по умолчанию (возможно, не то, что ожидалось!)
JonathanDavidArndt

Конечно, вы должны использовать const вместо того, чтобы звонить parseIntдважды
Кайл Делани

4

Делает ли работа намного чище, чем parseInt, по моему мнению, используйте оператор +

var s = '';
console.log(+s);

var s = '1024'
+s
1024

s = 0
+s
0

s = -1
+s
-1

s = 2.456
+s
2.456

s = ''
+s
0

s = 'wtf'
+s
NaN

1
Очень компактный Как жаль, что ты не получил больше очков. Я проголосовал за тебя. Пожалуйста, ответьте взаимностью, чтобы попытаться поймать мои -2, полученные сегодня немым троллем ... (см. Мой ответ в конце этой страницы). Спасибо.
Фабьен Хаддади


1

Сделайте отдельную проверку для пустой строки (поскольку это один конкретный случай) и установите ее в ноль в этом случае.

Вы можете добавить «0» в начало, но затем вам нужно добавить префикс, чтобы указать, что это десятичное число, а не восьмеричное число


так ты думаешь лучше добавить 0 если пусто?
Джопер

1
Нет - это подход, который я использовал. В этом случае отдельная проверка будет лучше. Однако, если решение Matts работает, это даже чище.
Кот Шредингера

1

Почему бы не переопределить функцию? В этом случае вы всегда можете быть уверены, что он вернется 0в случае NaN:

(function(original) {
    parseInt = function() {
        return original.apply(window, arguments) || 0;
    };
})(parseInt);

Теперь в любом месте вашего кода:

parseInt('') === 0

15
Отмена такой функции может сбить с толку опытных программистов на JavaScript, которые могут воспринимать это как ошибку. Ваша переопределенная функция, вероятно, будет похоронена где-то там, где ее вряд ли увидят. Это креативно, но я не уверен, что лично рекомендую его, учитывая, как просто добавить || 0ответ, как в ответе Мэтта. Я вижу, что переопределение объектов, которыми вы не владеете, является последним средством, или если вы этого не сделаете, это будет стоить значительно дороже с точки зрения времени и сложности.
jmort253

2
Я согласен с @ jmort253 ... Это опасно, потому что функция слишком умная. Лучше делать точно такую ​​же функцию, но с именем вроде getSafeNumberValue или чем-то в этом роде.
Самуил

1

У меня была похожая проблема (firefox v34) с простыми строками, такими как:

var myInt = parseInt("b4");

Итак, я придумал быстрый взлом:

var intVal = ("" + val).replace(/[^0-9]/gi, "");

А потом все глупо усложнилось, чтобы иметь дело с числами с плавающей запятой для непростых вещей:

var myval = "12.34";

function slowParseNumber(val, asInt){
    var ret = Number( ("" + val).replace(/[^0-9\.]/gi, "") );
    return asInt ? Math.floor(ret) : ret;
}
var floatVal = slowParseNumber(myval);

var intVal = slowParseNumber(myval, true);
console.log(floatVal, intVal);

Он вернет 0 для таких вещей, как:

var intVal = slowParseNumber("b"); // yeilds 0

1
//////////////////////////////////////////////////////
function ToInt(x){x=parseInt(x);return isNaN(x)?0:x;}
//////////////////////////////////////////////////////
var x = ToInt('');   //->  x=0
    x = ToInt('abc') //->  x=0
    x = ToInt('0.1') //->  x=0
    x = ToInt('5.9') //->  x=5
    x = ToInt(5.9)   //->  x=5
    x = ToInt(5)     //->  x=5

Можете ли вы объяснить это решение?
RamenChef

если вы хотите преобразовать любое число (например, «123» или «123») в целое число, если вы будете использовать parseInt («abc»),
AbdulRahman AlShamiri

если вы будете использовать parseInt ('abc'), вы попадете в NaN, но эта функция преобразует NaN в 0
AbdulRahman AlShamiri

Бинго, как явная альтернатива ||подходу. Я знаю, что это старый вопрос и ответ, но этот ответ избегает вызова parseInt дважды и использует isNaN правильно. Это просто нужно, чтобы основание parseInt(x, 10)было тщательным. (Я предпочитаю отдельную внутреннюю переменную вместо повторного использования x.)
goodeye

1

Я создал 2 прототипа, чтобы обработать это для меня, один для числа и один для строки.

// This is a safety check to make sure the prototype is not already defined.
Function.prototype.method = function (name, func) {
    if (!this.prototype[name]) {
        this.prototype[name] = func;
        return this;
    }
};

// returns the int value or -1 by default if it fails
Number.method('tryParseInt', function (defaultValue) {
    return parseInt(this) == this ? parseInt(this) : (defaultValue === undefined ? -1 : defaultValue);
});

// returns the int value or -1 by default if it fails
String.method('tryParseInt', function (defaultValue) {
    return parseInt(this) == this ? parseInt(this) : (defaultValue === undefined ? -1 : defaultValue);
});

Если вы не хотите использовать проверку безопасности, используйте

String.prototype.tryParseInt = function(){
    /*Method body here*/
};
Number.prototype.tryParseInt = function(){
     /*Method body here*/
};

Пример использования:

var test = 1;
console.log(test.tryParseInt()); // returns 1

var test2 = '1';
console.log(test2.tryParseInt()); // returns 1

var test3 = '1a';
console.log(test3.tryParseInt()); // returns -1 as that is the default

var test4 = '1a';
console.log(test4.tryParseInt(0));// returns 0, the specified default value

1
// implicit cast
var value = parseInt(tbb*1); // see original question

Объяснение, для тех, кто не считает это тривиальным:

Умножение на единицу, метод, называемый «неявное приведение», пытается превратить операнд неизвестного типа в примитивный тип «число». В частности, пустая строка станет номером 0, что делает ее подходящим типом для parseInt () ...

Очень хороший пример также привел выше PirateApp, который предложил добавить знак +, заставляя JavaScript использовать неявное приведение числа.


Это прямой ответ на оригинальный вопрос, мой дорогой.
Фабьен Хаддади

Это не будет делатьparseInt('str'*1)
Родион Баскаков

Зачем звонить parseIntна то, что уже является номером? Это повлечет за собой еще одно преобразование обратно в строку, только чтобы преобразовать это число снова.
Trincot

0

Кроме того, почему бы не написать функцию и вызывать ее там, где это необходимо. Я предполагаю, что это вход в поля формы для выполнения расчетов.

var Nanprocessor = function (entry) {
    if(entry=="NaN") {
        return 0;
    } else {
        return entry;
    }
}

 outputfield.value = Nanprocessor(x); 

// where x is a value that is collected from a from field
// i.e say x =parseInt(formfield1.value); 

что не так делает?


Привет, Ват мешает нам следовать вышеуказанному методу. Хотелось бы узнать узнать.
Нареш

3
Вы должны использовать isNaN для проверки NaN.
Мэтью

2
Спасибо, Мэтт :) Я не знаю, что в javascrip есть функция isNaN ()! Спасибо, что дал мне знать...!
Нареш

0

Вот метод tryParseInt, который я использую, он принимает значение по умолчанию в качестве второго параметра, поэтому он может быть любым, что вам нужно.

function tryParseInt(str, defaultValue) {
    return parseInt(str) == str ? parseInt(str) : defaultValue;
}

tryParseInt("", 0);//0 
tryParseInt("string", 0);//0 
tryParseInt("558", 0);//558

0

вспомогательная функция, которая все еще позволяет использовать основание

function parseIntWithFallback(s, fallback, radix) {
    var parsed = parseInt(s, radix);
    return isNaN(parsed) ? fallback : parsed;
}

0

Вы можете иметь очень чистый код, у меня были похожие проблемы, и я решил это с помощью:

var a="bcd";
~~parseInt(a);

0

Для других людей, которые ищут это решение, просто используйте: ~~ без parseInt, это самый чистый режим.

var a = 'hello';
var b = ~~a;

Если NaN, он вернет 0 вместо.

Обсервованный Это решение применимо только для целых чисел

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.