为何需用位运算符|0才能正确访问数组最后元素?代码解析
| 0 bitwise operator break access to the last element in my array intersection code? Problem Description
I have a function that finds the intersection of two string-formatted number arrays. For the input ["1, 3, 4, 7, 13", "1, 2, 4, 13, 15"], the expected result is 1,4,13. However, when I remove the | 0 bitwise operator from the code, the last intersecting element (13) isn't detected correctly. Here's my code:
function FindIntersection(strArr) { const firstArr = strArr[0].split(", "); const secondArr = strArr[1].split(", "); let newArr = []; let i = 0; let j = 0; while(i < firstArr.length && j < secondArr.length) { let a = firstArr[i] | 0; let b = secondArr[j] | 0; if(a === b) { newArr.push(a); i++; j++; } else if(a > b) { j++; } else if (b > a) { i++; } } strArr = newArr.join(","); return strArr; }
Why Removing | 0 Breaks the Code
The core issue boils down to string vs. numeric comparison behavior in JavaScript. When you split the input strings, every element in firstArr and secondArr is a string (e.g., "7", "13"), not a number. JavaScript compares strings lexicographically (like dictionary order) instead of by their actual numeric value.
Let’s walk through the exact failure point without | 0:
- When
i = 3,firstArr[i] = "7";j = 3,secondArr[j] = "13" - Comparing
"7">"13"as strings: The first character of"7"is"7"(ASCII code 55), while the first character of"13"is"1"(ASCII code 49). Since 55 > 49, JavaScript evaluates"7" > "13"astrue. - This triggers the
j++branch, movingjto 4 (element"15"). Comparing"7">"15"is stilltrue, sojincrements again to 5—exceedingsecondArr.length. The loop exits before it ever checks the"13"element infirstArr.
How | 0 Fixes the Problem
The | 0 bitwise OR operator is a concise way to convert a string (or any value) to a 32-bit integer. Here’s exactly what it does for your code:
- It takes string values like
"7"or"13"and converts them to their numeric equivalents (7,13). - Now, comparisons use actual numeric value instead of lexicographic order. So
7 > 13evaluates tofalse, and13 > 7istrue—which triggers thei++branch instead. - This lets the loop progress correctly:
iincrements until it reaches"13"(converted to 13), andjis still at"13"(converted to 13). The code detects the match, adds13to the result array, and finishes as expected.
Bonus: Explicit Alternatives to | 0
If you prefer more readable conversions, you can use these instead:
parseInt(firstArr[i], 10)(explicit base-10 integer conversion)Number(firstArr[i])(converts to a number, works for floats too)+firstArr[i](unary plus operator, behaves likeNumber())
All of these will fix the comparison issue—| 0 is just a shorthand (albeit slightly opaque) idiom for integer conversion in JavaScript.
内容的提问来源于stack exchange,提问作者Benedikt

