首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >复制cljc项目的String.hashCode()方法

复制cljc项目的String.hashCode()方法
EN

Stack Overflow用户
提问于 2019-07-31 10:39:06
回答 2查看 158关注 0票数 0

我有一个应该同时作为clj和cljs项目工作的项目,它目前使用Java的hashCode进行散列,我不能改变这一点。我需要找到一种方法来为cljs场景实现相同的解决方案。

我有相同散列过程的javascript实现所需的代码,我认为理想情况下,我希望对clj和cljs场景都使用此函数,因为这是我所知道的最快的散列方式。

代码语言:javascript
复制
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

代码语言:javascript
复制
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],但是没有效果。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-08-02 03:01:36

您的hashCode.js是一个闭包库,因此可以使用:libs编译器选项来访问它。这在依赖关系页面上有更详细的描述。

(请注意,您的源代码中有一个错误;应该将p1替换为stringToHash。)

下面是一个使用:libs访问实现的示例:

代码语言:javascript
复制
$ 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的一个比较直接的转换是:

代码语言:javascript
复制
(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)))

虽然闭包库附带了一个与记录在案类似的字符串记录在案实现,但它可能不适合您使用,因为它不会生成有符号的哈希值:

代码语言:javascript
复制
cljs.user=> (goog.string/hashCode "hello")
99162322
cljs.user=> (goog.string/hashCode "abcdef")
2870581347
票数 0
EN

Stack Overflow用户

发布于 2019-07-31 16:18:45

以下是一个解决方案:

代码语言:javascript
复制
(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"))
  )

有结果

代码语言:javascript
复制
-------------------------------
   Clojure 1.10.0    Java 12
-------------------------------

Testing tst.demo.core
:spy => "hello"
(str->hashcode "hello") => 99162322
(.hashCode "hello") => 99162322

永远记住Clojure/ClojureSciprt CheatSheet

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57288865

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档