[javascript] JavaScript에는 해시 코드 함수가 있습니까?

기본적으로 고유 한 객체, 세트의 객체를 만들려고합니다. 속성 이름에 대한 객체와 함께 JavaScript 객체를 사용한다는 훌륭한 아이디어가있었습니다. 같은

set[obj] = true;

이것은 한 지점까지 작동합니다. 문자열과 숫자로 잘 작동하지만 다른 객체에서는 모두 같은 값으로 “해시”되어 같은 속성에 액세스하는 것 같습니다. 객체에 대해 고유 한 해시 값을 생성 할 수있는 방법이 있습니까? 문자열과 숫자는 어떻게합니까, 같은 동작을 무시할 수 있습니까?



답변

JavaScript 객체는 문자열을 키로 만 사용할 수 있습니다 (다른 것은 문자열로 변환 됨).

또는 해당 객체를 인덱싱하는 배열을 유지 관리하고 해당 인덱스 문자열을 객체에 대한 참조로 사용할 수 있습니다. 이 같은:

var ObjectReference = [];
ObjectReference.push(obj);

set['ObjectReference.' + ObjectReference.indexOf(obj)] = true;

분명히 조금 장황하지만, 그것을 처리하고 모든 Willy nilly를 가져오고 설정할 수있는 몇 가지 메소드를 작성할 수 있습니다.

편집하다:

당신의 추측은 사실입니다-이것은 JavaScript에서 동작으로 정의됩니다-특히 toString 변환이 발생하여 속성 이름으로 사용될 객체에서 자신의 toString 함수를 정의 할 수 있습니다. -올리에

이것은 또 다른 흥미로운 점을 제시합니다. 해시하려는 객체에 toString 메서드를 정의하면 해시 식별자를 구성 할 수 있습니다.


답변

JavaScript에서 Java와 같은 hashCode () 함수를 원한다면 다음과 같습니다.

String.prototype.hashCode = function(){
    var hash = 0;
    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;
}

이것이 Java (비트 연산자)의 구현 방식입니다.

hashCode는 양수 및 음수 일 수 있으며, 정상 입니다. 음수 값을 제공하는 HashCode를 참조하십시오 . 따라서이 Math.abs()기능과 함께 사용하는 것을 고려할 수 있습니다 .


답변

가장 쉬운 방법은 각 객체에 고유 한 toString방법을 제공하는 것입니다.

(function() {
    var id = 0;

    /*global MyObject */
    MyObject = function() {
        this.objectId = '<#MyObject:' + (id++) + '>';
        this.toString= function() {
            return this.objectId;
        };
    };
})();

나는 같은 문제가 있었고 이것은 최소한의 소란으로 나를 위해 완벽하게 해결했으며 지방 자바 스타일을 다시 구현하고 객체 클래스에 Hashtable추가 equals()하고 hashCode()객체 클래스에 추가 하는 것이 훨씬 쉽습니다 . 문자열 ‘<#MyObject : 12>도 해시에 넣지 않아야합니다. 그렇지 않으면 해당 ID를 가진 기존 객체의 항목이 지워집니다.

이제 내 해시는 모두 차갑습니다. 나는 또한 이 정확한 주제 에 대해 며칠 전에 블로그 항목을 게시했습니다 .


답변

설명한 내용은 ECMAScript 6 사양 (다음 JavaScript 버전)의 일부인 Harmony WeakMaps 에서 다룹니다 . 즉, 키는 정의되지 않은 것을 포함하여 무엇이든 될 수 있고 열거 할 수없는 세트입니다.

즉, 키에 연결된 키 (객체!)에 대한 직접적인 참조가 없으면 값에 대한 참조를 얻을 수 없습니다. 효율성 및 가비지 수집과 관련된 여러 가지 엔진 구현 이유에서 중요하지만 데이터 전송자를 노출시키지 않고 회전 가능한 액세스 권한 및 데이터 전달과 같은 새로운 의미를 허용한다는 점에서도 매우 훌륭합니다.

에서 MDN :

var wm1 = new WeakMap(),
    wm2 = new WeakMap();
var o1 = {},
    o2 = function(){},
    o3 = window;

wm1.set(o1, 37);
wm1.set(o2, "azerty");
wm2.set(o1, o2); // A value can be anything, including an object or a function.
wm2.set(o3, undefined);
wm2.set(wm1, wm2); // Keys and values can be any objects. Even WeakMaps!

wm1.get(o2); // "azerty"
wm2.get(o2); // Undefined, because there is no value for o2 on wm2.
wm2.get(o3); // Undefined, because that is the set value.

wm1.has(o2); // True
wm2.has(o2); // False
wm2.has(o3); // True (even if the value itself is 'undefined').

wm1.has(o1);   // True
wm1.delete(o1);
wm1.has(o1);   // False

WeakMaps는 현재 Firefox, Chrome 및 Edge에서 사용할 수 있습니다. 또한 노드 v7 및 v6에서 --harmony-weak-maps플래그가 지원됩니다.


답변

내가 선택한 솔루션은 Daniel과 유사하지만 객체 팩토리를 사용하고 toString을 재정의하는 대신 getHashCode 함수를 통해 처음 요청 될 때 객체에 해시를 명시 적으로 추가합니다. 조금 지저분하지만 내 요구에 더 좋습니다 🙂

Function.prototype.getHashCode = (function(id) {
    return function() {
        if (!this.hashCode) {
            this.hashCode = '<hash|#' + (id++) + '>';
        }
        return this.hashCode;
    }
}(0));


답변

특정 상황에서는 키와 프리미티브 값이 진행되는 한 객체의 평등에만 관심이 있습니다. 나를 위해 일한 솔루션은 객체를 JSON 표현으로 변환하고 해시로 사용하는 것이 었습니다. 잠재적으로 일치하지 않는 키 정의 순서와 같은 제한 사항이 있습니다. 그러나 내가 말했듯 이이 객체는 모두 한곳에서 생성 되었기 때문에 저에게 효과적이었습니다.

var hashtable = {};

var myObject = {a:0,b:1,c:2};

var hash = JSON.stringify(myObject);
// '{"a":0,"b":1,"c":2}'

hashtable[hash] = myObject;
// {
//   '{"a":0,"b":1,"c":2}': myObject
// }


답변

문자열, 객체, 배열 등에 대한 해시 코드를 생성하기 위해 작은 JavaScript 모듈 을 얼마 전에 함께 사용 했습니다 (방금 GitHub에 커밋했습니다. )

용법:

Hashcode.value("stackoverflow")
// -2559914341
Hashcode.value({ 'site' : "stackoverflow" })
// -3579752159