/** | |
* 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 |
Using let
function hashCode(s) {
for(let i = 0, h = 0; i < s.length; i++)
h = Math.imul(31, h) + s.charCodeAt(i) | 0;
return h;
}
Using
let
function hashCode(s) { for(let i = 0, h = 0; i < s.length; i++) h = Math.imul(31, h) + s.charCodeAt(i) | 0; return h; }
Since you've changed var
to let
, variable h
now must be declared outside the for loop.
function hashCode(s) {
let h;
for(let i = 0; i < s.length; i++)
h = Math.imul(31, h) + s.charCodeAt(i) | 0;
return h;
}
What about a hashCode of an object in JS? Maybe that can only happen in C/C++ land.
@ORESoftware you may be interested in https://github.com/puleos/object-hash
Alternative using arrays:
function hashCode(str) {
return Array.from(str)
.reduce((s, c) => Math.imul(31, s) + c.charCodeAt(0) | 0, 0)
}
Thank you.
hashCode = function(s) {
var h = 0, i = s.length - 1;
while (i >= 0)
h = (h << 5) - h + s.charCodeAt(--i) | 0;
return h;
};
One less local variable and one less if.
the last char will be ignored and in a last iteration you try to take charCode for -1
hashCode = function(s) {
var h = 0, i = s.length;
while (i > 0) {
h = (h << 5) - h + s.charCodeAt(--i) | 0;
}
return h;
};
Using
let
function hashCode(s) { for(let i = 0, h = 0; i < s.length; i++) h = Math.imul(31, h) + s.charCodeAt(i) | 0; return h; }Since you've changed
var
tolet
, variableh
now must be declared outside the for loop.function hashCode(s) { let h; for(let i = 0; i < s.length; i++) h = Math.imul(31, h) + s.charCodeAt(i) | 0; return h; }
For s.length === 0 :)
function hashCode(s) {
let h=0;
for(let i = 0; i < s.length; i++)
h = Math.imul(31, h) + s.charCodeAt(i) | 0;
return h;
}
A comprehensive list of general purpose hash functions and their implementations can found here:
Alternative using arrays:
function hashCode(str) { return Array.from(str) .reduce((s, c) => Math.imul(31, s) + c.charCodeAt(0) | 0, 0) }
A one liner version
const hashCode = (str) => [...str].reduce((s, c) => Math.imul(31, s) + c.charCodeAt(0) | 0, 0)
Source: https://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript
/**
* @see http://stackoverflow.com/q/7616461/940217
* @return {number}
*/
String.prototype.hashCode = function(){
if (Array.prototype.reduce){
return this.split("").reduce(function(a,b){a=((a<<5)-a)+b.charCodeAt(0);return a&a},0);
}
var hash = 0;
if (this.length === 0) return hash;
for (var i = 0; i < this.length; i++) {
var character = this.charCodeAt(i);
hash = ((hash<<5)-hash)+character;
hash = hash & hash; // Convert to 32bit integer
}
return hash;
}
Use:
console.log(
String('[').hashCode(),
String('a').hashCode(),
String(']').hashCode(),
String('[a]').hashCode(),
String('[a]').hashCode()
)
// Output:
// 91 97 93 90551 90551
/**
* Returns a UUIDv4 as string
*
* @returns {string}
*/
generateUuid = () => {
return (
String('xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx')
).replace(/[xy]/g, (character) => {
const random = (Math.random() * 16) | 0;
const value = character === "x" ? random : (random & 0x3) | 0x8;
return value.toString(16);
});
};
generateUuid()
Here's even faster implementation of the original using ES6 reduce.
function hashCode(s) {
return [...s].reduce(
(hash, c) => (Math.imul(31, hash) + c.charCodeAt(0)) | 0,
0
);
}
Tested in Chrome (112.0 v)
- Original (while loop): 2.40087890625 ms
- Modified (for loop): 3.412109375 ms
- New (reduce): 1.150146484375 ms
@Super-Chama you copied the answer from @4nte ...
@martin-juul no, look again.
Faster version using ES6
Math.imul
for fun!If you're wondering about the
| 0
part, it forcesh
to be a 32-bit number, optimizing for speed in JS engines.