Ich kombinierte die Antworten von Augenlidlosigkeit und KimKha.
Das Folgende ist ein AngularJS-Dienst, der Zahlen, Zeichenfolgen und Objekte unterstützt.
exports.Hash = () => {
let hashFunc;
function stringHash(string, noType) {
let hashString = string;
if (!noType) {
hashString = `string${string}`;
}
var hash = 0;
for (var i = 0; i < hashString.length; i++) {
var character = hashString.charCodeAt(i);
hash = ((hash<<5)-hash)+character;
hash = hash & hash; // Convert to 32bit integer
}
return hash;
}
function objectHash(obj, exclude) {
if (exclude.indexOf(obj) > -1) {
return undefined;
}
let hash = '';
const keys = Object.keys(obj).sort();
for (let index = 0; index < keys.length; index += 1) {
const key = keys[index];
const keyHash = hashFunc(key);
const attrHash = hashFunc(obj[key], exclude);
exclude.push(obj[key]);
hash += stringHash(`object${keyHash}${attrHash}`, true);
}
return stringHash(hash, true);
}
function Hash(unkType, exclude) {
let ex = exclude;
if (ex === undefined) {
ex = [];
}
if (!isNaN(unkType) && typeof unkType !== 'string') {
return unkType;
}
switch (typeof unkType) {
case 'object':
return objectHash(unkType, ex);
default:
return stringHash(String(unkType));
}
}
hashFunc = Hash;
return Hash;
};
Anwendungsbeispiel:
Hash('hello world'), Hash('hello world') == Hash('hello world')
Hash({hello: 'hello world'}), Hash({hello: 'hello world'}) == Hash({hello: 'hello world'})
Hash({hello: 'hello world', goodbye: 'adios amigos'}), Hash({hello: 'hello world', goodbye: 'adios amigos'}) == Hash({goodbye: 'adios amigos', hello: 'hello world'})
Hash(['hello world']), Hash(['hello world']) == Hash(['hello world'])
Hash(1), Hash(1) == Hash(1)
Hash('1'), Hash('1') == Hash('1')
Ausgabe
432700947 true
-411117486 true
1725787021 true
-1585332251 true
1 true
-1881759168 true
Erläuterung
Wie Sie sehen können, ist das Herzstück des Dienstes die von KimKha erstellte Hash-Funktion. Ich habe den Zeichenfolgen Typen hinzugefügt, damit sich die Struktur des Objekts auch auf den endgültigen Hash-Wert auswirkt. Die Schlüssel werden gehasht, um Kollisionen zwischen Array und Objekt zu verhindern.
Der Objektvergleich ohne Augenlid wird verwendet, um eine unendliche Rekursion durch selbstreferenzierende Objekte zu verhindern.
Verwendung
Ich habe diesen Dienst erstellt, damit ich einen Fehlerdienst haben kann, auf den mit Objekten zugegriffen wird. Damit ein Dienst einen Fehler mit einem bestimmten Objekt registrieren kann und ein anderer feststellen kann, ob Fehler gefunden wurden.
dh
JsonValidation.js
ErrorSvc({id: 1, json: '{attr: "not-valid"}'}, 'Invalid Json Syntax - key not double quoted');
UserOfData.js
ErrorSvc({id: 1, json: '{attr: "not-valid"}'});
Dies würde zurückkehren:
['Invalid Json Syntax - key not double quoted']
Während
ErrorSvc({id: 1, json: '{"attr": "not-valid"}'});
Dies würde zurückkehren
[]