我有一个应该同时作为clj和cljs项目工作的项目,它目前使用Java的hashCode进行散列,我不能改变这一点。我需要找到一种方法来为cljs场景实现相同的解决方案。
我有相同散列过程的javascript实现所需的代码,我认为理想情况下,我希望对clj和cljs场景都使用此函数,因为这是我所知道的最快的散列方式。
hashCode = function(stringToHash){
let hash = 0;
if (stringToHash.length === 0) return hash;
let char;
for (i = 0; i < p1.length; i++) {
char = stringToHash.charCodeAt(i);
hash = ((hash << 5) - hash) + char;
hash = hash & hash; // Convert to 32bit integer
}
return hash;
};另一种选择是在纯clojure中重新创建散列算法,但我认为这会导致性能下降。因此,我的问题要么是如何将这个js方法正确地要求到cljc项目中,要么是如何在clojure中重新创建相同的算法。
这是我的`hashCode.js
goog.provide('hashCode');
/**
* @param {string} stringToHash
* @return {number}
*/
hashCode.hashCode = function(stringToHash){
let hash = 0;
if (stringToHash.length === 0) return hash;
let char;
for (i = 0; i < p1.length; i++) {
char = stringToHash.charCodeAt(i);
hash = ((hash << 5) - hash) + char;
hash = hash & hash; // Convert to 32bit integer
}
return hash;
};我已经尝试过在我的core.cljc文件中要求这样的[hashCode :as hs],但是没有效果。
发布于 2019-08-02 03:01:36
您的hashCode.js是一个闭包库,因此可以使用:libs编译器选项来访问它。这在依赖关系页面上有更详细的描述。
(请注意,您的源代码中有一个错误;应该将p1替换为stringToHash。)
下面是一个使用:libs访问实现的示例:
$ clj -m cljs.main -co '{:libs ["hashCode.js"]}' -r
ClojureScript 1.10.520
cljs.user=> (require '[hashCode :as hs])
nil
cljs.user=> (hs/hashCode "hello")
99162322
cljs.user=> (hs/hashCode "abcdef")
-1424385949(请注意,如果使用:advanced :optimizations,因为您的代码使用了let,所以还需要将:language-in指定为:es6。)
将该实现转换为ClojureScript的一个比较直接的转换是:
(defn string-hash [s]
(loop [i 0 h 0]
(if (< i (.-length s))
(let [c (.charCodeAt s i)
h (+ (- (bit-shift-left h 5) h) c)]
(recur (inc i) (bit-and h h)))
h)))虽然闭包库附带了一个与记录在案类似的字符串记录在案实现,但它可能不适合您使用,因为它不会生成有符号的哈希值:
cljs.user=> (goog.string/hashCode "hello")
99162322
cljs.user=> (goog.string/hashCode "abcdef")
2870581347发布于 2019-07-31 16:18:45
以下是一个解决方案:
(ns tst.demo.core
(:use demo.core tupelo.core tupelo.test)
(:require [tupelo.core :as t]) )
(defn str->hashcode
"Work-alike impl of Java String.hashCode() fn"
[str-val]
(let [char-codes (mapv int str-val)
step-fn (fn step-fn [hash-in char-code]
(let [hash-out (+ char-code
(-
(bit-shift-left hash-in 5)
hash-in))
hash-out (bit-and hash-out 0xFFFFFFFF)]
hash-out))
result (reduce step-fn 0 char-codes)]
result))
(dotest
(spy "hello")
(spyx (str->hashcode "hello"))
(spyx (.hashCode "hello"))
)有结果
-------------------------------
Clojure 1.10.0 Java 12
-------------------------------
Testing tst.demo.core
:spy => "hello"
(str->hashcode "hello") => 99162322
(.hashCode "hello") => 99162322永远记住Clojure/ClojureSciprt CheatSheet
https://stackoverflow.com/questions/57288865
复制相似问题