Recent frequent problems of 'parseInt' and 'Array' prototype methods

Keywords: Javascript

First look at the function signature of parseInt

/**
 * Converts a string to an integer.
 * @param s The value to be resolved. If the parameter is not a string, convert it to a string (using ToString abstraction). Whitespace at the beginning of the string will be ignored.
 * @param radix An integer between 2 and 36 (the basis of the mathematical system) that represents the cardinality of the above string.
 * If this parameter is not provided, the string starting with '0x' will be recognized as a hexadecimal number
 * In other cases, different environments have different processing methods, which are generally recognized as decimal numbers
 * If 0 null undefined and so on are passed in, this parameter is not provided for processing
 * If the input is not a number, the parameter will be converted to a number. If it cannot be converted, the parameter will not be provided for processing
 * If you do not provide this parameter, different platforms may have different platforms, so please explicitly provide this parameter
 */
declare function parseInt(s: string, radix?: number): number;

You can see that parseInt actually has two parameters, one is a required s, and the type is string;
There is also an optional radius, which is used to represent the base. For example, if you fill in 10, the first parameter will be parsed into decimal. If you fill in 16, the string passed in will be parsed into sixteen mechanism. In principle, it is better to fill in all the parameters.
The return value is an integer. If the first character of the parsed parameter cannot be converted to a numeric type, NaN is returned.

A few simple examples

The following piles all return to 15

parseInt('0xF', 16);
parseInt('F', 16);
parseInt('17', 8);
parseInt(021, 8);
parseInt('015', 10); // parseInt(015, 10); return 15
parseInt(15.99, 10);
parseInt('15,123', 10);
parseInt('FXX123', 16);
parseInt('1111', 2);
parseInt('15 * 3', 10);
parseInt('15e2', 10);
parseInt('15px', 10);
parseInt('12', 13);

The following examples all return - 15

parseInt('-F', 16);
parseInt('-0F', 16);
parseInt('-0XF', 16);
parseInt(-15.1, 10);
parseInt(' -17', 8);
parseInt(' -15', 10);
parseInt('-1111', 2);
parseInt('-15e1', 10);
parseInt('-12', 13);

The following examples all return NaN

parseInt('Hello', 8); // It's not a number at all
parseInt('546', 2); // No other number is a valid binary number except "0, 1"
parseInt('zz', 35); // z is 35. It can't be 35 in base 35

Return to the example of NaN and change it

parseInt('Hello', 18); // 320, H = 17 e = 14 l = 21, resolvable He 17 * 18 ^ 1 + 14 * 18 ^ 0 = 320
// 188275, H = 17 e = 14 l = 21, the parsed hel 17 * 22 ^ 3 + 14 * 22 ^ 2 + 21 * 22 ^ 1 + 21 * 22 ^ 0 = 188275
parseInt('Hello', 22);
parseInt('546', 10); // 546 don't say that
parseInt('zz', 36); // 1295 z = 35,35 * 36 ^ 1 + 35 * 36 ^ 0 = 1295

After passing in the number, the following examples all return 4, first toString(), and then the decimal point cannot be resolved

parseInt(4.7, 10);
parseInt(4.7 * 1e22, 10); // A very large number becomes 4
parseInt(0.00000000000434, 10); // A very small number becomes 4

Recent interview questions and variations

[1,2,3].map(parseInt)
// [1, NaN, NaN]
map<U>(callbackfn: (value: T, index: number, array: ReadonlyArray<T>) => U, thisArg?: any): U[];

I think many people know the answer. In the calculation process, we need to know some map function signatures. The first parameter of map is callback function, which has three parameters. Although the third parameter is usually not used, parseInt accepts two parameters, so it runs in practice

[1, 2, 3].map((value, index) => parseInt(value, index));

The three calculation processes are

  • parseInt(1, 0), decimal, return 1
  • parseInt(2, 1), base cannot be 1, return NaN
  • parseInt(3, 2). It is impossible to find 3 in binary. Return NaN
[1, 2, 3].filter(parseInt); //[1]
[1, 2, 3].find(parseInt); // 1
[1, 2, 3].findIndex(parseInt); // 0

The callback function signature of filter is the same as that of map. The function of filter is to filter out the function whose return value is false,
Find is to find the item whose first return value is true. Find index is to find the index whose first return value is true

Calculus process

  • parseInt(1, 0), decimal processing, return 1, true value, find return 1, findIndex return 0,
  • parseInt(2, 1), cardinality cannot be 1, return NaN, false value, filtered
  • parseInt(3, 2), which is impossible to appear in binary, returns NaN, false value, filtered

Here, find and findIndex can be used for short-circuit operation. If they encounter true, they will exit. They can replace forEach, which cannot exit through return, but the code semantics is weak.

[1,2,3].reduce(parseInt)
// 1
reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: ReadonlyArray<T>) => T, initialValue: T): T;

There are four callback parameters of reduce, one is the value returned in the last cycle, one is the current value, one is the current value index, and one is the original array. There is no initial value involved in this problem, so the iteration starts from 2.

The two calculation processes are as follows:

  • parseInt(1, 2), binary 1, is also 1 when converted to decimal system. At this time, return 1 to enter the next iteration
  • parseInt(1, 3), the second iteration, the last iteration's value is 1, the current value is 3, the ternary 1, return 1
[1, 2, 3].reduceRight(parseInt);
// NaN

The signature of reduceRight is the same as that of reduce, but the iteration starts from the right.

The two calculation processes are as follows:

  • parseInt(3, 2), binary 3, return NaN
  • parseInt(NaN, 1), the second iteration, the last iteration value is NaN, the current value is 1, the cardinality is 1, return NaN
[1, 2, 3].some(parseInt); // true
[1, 2, 3].every(parseInt); // false

The callback function signature of some every is the same as that of map. If some has a true value, it returns true. If every is all true, it returns true.

The calculation process is

  • parseInt(1, 0), decimal processing, return 1, true value, some return true, operation end
  • parseInt(2, 1), cardinality cannot be 1, return NaN, false value, every return false, operation end

It is mentioned here that some and every can be used for short-circuit operation. When some encounters true, it will exit. When every encounters false, it will exit. It can be used to replace forEach, which cannot exit through return, but the code semantics is weak.

[1, 2, 3].forEach(parseInt); // true
// undefined

If the answer to this question is wrong, I really want to slap myself....

[1, 2, 3].map(parseInt); has it been type converted? Yes, we have. Because parseInt will transfer the first parameter passed in. If it is not a string, it will be converted to a string. Here is a type conversion

Written in the end

An API seems to be very simple. In fact, there are many ways to test it. If you don't understand it carefully, you won't know its principle.

Posted by AcousticJames on Wed, 06 Nov 2019 01:09:41 -0800