-
-
Save hyamamoto/fd435505d29ebfa3d9716fd2be8d42f0 to your computer and use it in GitHub Desktop.
/** | |
* Returns a hash code for a string. | |
* (Compatible to Java's String.hashCode()) | |
* | |
* The hash code for a string object is computed as | |
* s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1] | |
* using number arithmetic, where s[i] is the i th character | |
* of the given string, n is the length of the string, | |
* and ^ indicates exponentiation. | |
* (The hash value of the empty string is zero.) | |
* | |
* @param {string} s a string | |
* @return {number} a hash code value for the given string. | |
*/ | |
hashCode = function(s) { | |
var h = 0, l = s.length, i = 0; | |
if ( l > 0 ) | |
while (i < l) | |
h = (h << 5) - h + s.charCodeAt(i++) | 0; | |
return h; | |
}; |
> hashCode('') | |
0 | |
> hashCode('Hello') | |
69609650 |
@ngp33 there's at least 5 differences. my point is, i didn't copy anyone's code. I would happily give credit if i did. I saw the original implementation and thought reduce will be nicer than loop and faster. so i wrote my own, tested with console.time
and posted for anyone coming into this thread. but i'll update my comment as precaution
@martin-juul What's your point? this whole thread is entirely derivative, and there's only so many ways to continually add a sequence of numbers and multiply by 31 in a loop. We're talking about one line of code basically. People modified my code and I did not care, because it's far too basic.
@Super-Chama Hmm, that version appears to in fact be noticeably slower (than my for
loop version at least). It could be that either the spread operator or reduce
is slowing things down in batch operations, not sure which. See benchmark: https://jsbench.me/vcljn1em32
I tried to use this method in my project but it didn't seem to spread out adjacent inputs very well:
for (let i = 0; i < 1000; i++) {
console.log(hashCode("" + i));
}
48 49 50 51 52 53 54 55 56 57 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700
I found this awesome single file module that works great though:
https://github.com/garycourt/murmurhash-js
Just FYI, another take on the same problem here, with both an old Java-style hash and with a version of @bryc's excellent, more modern cyrb53 hash:
https://gist.github.com/jlevy/c246006675becc446360a798e2b2d781
What about a hashCode of an object in JS? Maybe that can only happen in C/C++ land.
You can use JSON.stringify(object) to turn it into a string first, then encode, then when you decode, turn it back into an object with JSON.parse()
So no one else wastes time looking for the difference (there is none):