热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

JavaScript中有哈希代码函数吗?-IsthereanykindofhashcodefunctioninJavaScript?

Basically,Imtryingtocreateanobjectofuniqueobjects,aset.Ihadthebrilliantideaofjust

Basically, I'm trying to create an object of unique objects, a set. I had the brilliant idea of just using a Javascript object with objects for the property names. Such as,

基本上,我正在尝试创建一个对象的唯一对象,一个集合。例如,

set[obj] = true;

This works, up to a point. It works great with string and numbers, but with other objects, they all seem to "hash" to the same value and access the same property. Is there some kind of way I can generate a unique hash value for an object? How do strings and numbers do it, can I override the same behavior?

这在一定程度上是可行的。它可以很好地处理字符串和数字,但是对于其他对象,它们似乎都可以“哈希”到相同的值并访问相同的属性。是否有某种方法可以为对象生成唯一的哈希值?字符串和数字是怎么做的,我能重写相同的行为吗?

16 个解决方案

#1


32  

Javascript objects can only use strings as keys (anything else is converted to a string).

Javascript对象只能使用字符串作为键(其他任何东西都被转换为字符串)。

You could, alternatively, maintain an array which indexes the objects in question, and use its index string as a reference to the object. Something like this:

或者,您可以维护一个数组,该数组对相关对象进行索引,并使用其索引字符串作为对象的引用。是这样的:

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

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

Obviously it's a little verbose, but you could write a couple of methods that handle it and get and set all willy nilly.

显然,它有点冗长,但是您可以编写一些方法来处理它,然后获取和设置所有的威利。

Edit:

编辑:

Your guess is fact -- this is defined behaviour in Javascript -- specifically a toString conversion occurs meaning that you can can define your own toString function on the object that will be used as the property name. - olliej

您的猜测是事实——这是Javascript中定义的行为——特别是发生了toString转换,这意味着您可以在对象上定义自己的toString函数,该对象将用作属性名。——olliej

This brings up another interesting point; you can define a toString method on the objects you want to hash, and that can form their hash identifier.

这引出了另一个有趣的观点;您可以在想要散列的对象上定义一个toString方法,这可以形成它们的散列标识符。

#2


38  

If you want a hashCode() function like Java's in Javascript, that is yours:

如果您想要一个hashCode()函数,如Javascript中的Java,那就是您的:

String.prototype.hashCode = function(){
    var hash = 0;
    for (var i = 0; i 

That is the way of implementation in Java (bitwise operator).

这就是Java中的实现方式(位操作符)。

#3


32  

The easiest way to do this is to give each of your objects its own unique toString method:

要做到这一点,最简单的方法就是给你的每个对象一个独特的toString方法:

(function() {
    var id = 0;

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

I had the same problem and this solved it perfectly for me with minimal fuss, and was a lot easier that re-implementing some fatty Java style Hashtable and adding equals() and hashCode() to your object classes. Just make sure that you don't also stick a string '<#MyObject:12> into your hash or it will wipe out the entry for your exiting object with that id.

我也遇到了同样的问题,这就很好地为我解决了这个问题,而且很容易重新实现一些胖Java风格的散列表,并向对象类添加equals()和hashCode()。只要确保您不将字符串'<#MyObject:12>插入到您的散列中,否则它将用该id清除退出对象的条目。

Now all my hashes are totally chill. I also just posted a blog entry a few days ago about this exact topic.

现在我所有的散列都是冷的。几天前,我刚刚就这个话题发表了一篇博客文章。

#4


18  

The solution I chose is similar to Daniel's, but rather than use an object factory and override the toString, I explicitly add the hash to the object when it is first requested through a getHashCode function. A little messy, but better for my needs :)

我选择的解决方案与Daniel的类似,但我没有使用对象工厂并覆盖toString,而是在通过getHashCode函数首次请求对象时显式地将散列添加到对象中。有点乱,但更符合我的需要:)

Function.prototype.getHashCode = (function(id) {
    return function() {
        if (!this.hashCode) {
            this.hashCode = '';
        }
        return this.hashCode;
    }
}(0));

#5


16  

What you described is covered by Harmony WeakMaps, part of the ECMAScript 6 specification (next version of Javascript). That is: a set where the keys can be anything (including undefined) and is non-enumerable.

您所描述的是Harmony WeakMaps,它是ECMAScript 6规范(Javascript的下一个版本)的一部分。即:一个集合,其中的键可以是任何东西(包括未定义的),并且是不可枚举的。

This means it's impossible to get a reference to a value unless you have a direct reference to the key (any object!) that links to it. It's important for a bunch of engine implementation reasons relating to efficiency and garbage collection, but it's also super cool for in that it allows for new semantics like revokable access permissions and passing data without exposing the data sender.

这意味着不可能获得对值的引用,除非您有指向该值的键(任何对象!)的直接引用。对于与效率和垃圾收集相关的许多引擎实现原因来说,这很重要,但它也非常酷,因为它允许新的语义,比如撤销访问权限和传递数据,而不暴露数据发送者。

From 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 are available in current Firefox, Chrome and Edge. They're also supported in Node v7 , and in v6 with the --harmony-weak-maps flag.

弱地图可以在当前的Firefox、Chrome和Edge中使用。它们在节点v7中也得到了支持,在v6中也有—谐波-弱映射标志。

#6


8  

For my specific situation I only care about the equality of the object as far as keys and primitive values go. The solution that worked for me was converting the object to its JSON representation and using that as the hash. There are limitations such as order of key definition potentially being inconsistent; but like I said it worked for me because these objects were all being generated in one place.

对于我的具体情况,我只关心键和原始值之间的相等性。我的解决方案是将对象转换为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
// }

#7


8  

The Javascript specification defines indexed property access as performing a toString conversion on the index name. For example,

Javascript规范将索引属性访问定义为对索引名执行toString转换。例如,

myObject[myProperty] = ...;

is the same as

是一样的

myObject[myProperty.toString()] = ...;

This is necessary as in Javascript

这是必需的,就像在Javascript中一样

myObject["someProperty"]

is the same as

是一样的

myObject.someProperty

And yes, it makes me sad as well :-(

是的,这也让我难过

#8


8  

I put together a small Javascript module a while ago to produce hashcodes for strings, objects, arrays, etc. (I just committed it to GitHub :) )

我不久前组装了一个小的Javascript模块,为字符串、对象、数组等生成hashcode(我只是将它提交给GitHub:)。

Usage:

用法:

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

#9


6  

In ECMAScript 6 there's now a Set that works how you'd like: https://developer.mozilla.org/en-US/docs/Web/Javascript/Reference/Global_Objects/Set

在ECMAScript 6中,现在有一个设置可以按照您的要求工作:https://developer.mozilla.org/en-US/docs/Web/Javascript/Reference/Global_Objects/Set

It's already available in the latest Chrome, FF, and IE11.

它已经在最新的Chrome、FF和IE11中可用。

#10


3  

Reference: https://developer.mozilla.org/en-US/docs/Web/Javascript/Reference/Global_Objects/Symbol

参考:https://developer.mozilla.org/en-US/docs/Web/Javascript/Reference/Global_Objects/Symbol

you can use Es6 symbol to create unique key and access object. Every symbol value returned from Symbol() is unique. A symbol value may be used as an identifier for object properties; this is the data type's only purpose.

您可以使用Es6符号来创建唯一的密钥和访问对象。从symbol()返回的每个符号值都是惟一的。符号值可以用作对象属性的标识符;这是数据类型的唯一用途。

var obj = {};

obj[Symbol('a')] = 'a';
obj[Symbol.for('b')] = 'b';
obj['c'] = 'c';
obj.d = 'd';

#11


1  

My solution introduces a static function for the global Object object.

我的解决方案为全局对象对象引入了一个静态函数。

(function() {
    var lastStorageId = 0;

    this.Object.hash = function(object) {
        var hash = object.__id;

        if (!hash)
             hash = object.__id = lastStorageId++;

        return '#' + hash;
    };
}());

I think this is more convenient with other object manipulating functions in Javascript.

我认为在Javascript中使用其他对象操作函数更方便。

#12


1  

Here's my simple solution that returns a unique integer.

下面是返回唯一整数的简单解决方案。

function hashcode(obj) {
    var hc = 0;
    var chars = JSON.stringify(obj).replace(/\{|\"|\}|\:|,/g, '');
    var len = chars.length;
    for (var i = 0; i 

#13


0  

If you truly want set behavior (I'm going by Java knowledge), then you will be hard pressed to find a solution in Javascript. Most developers will recommend a unique key to represent each object, but this is unlike set, in that you can get two identical objects each with a unique key. The Java API does the work of checking for duplicate values by comparing hash code values, not keys, and since there is no hash code value representation of objects in Javascript, it becomes almost impossible to do the same. Even the Prototype JS library admits this shortcoming, when it says:

如果您确实想要设置行为(我是用Java知识编写的),那么您将很难在Javascript中找到解决方案。大多数开发人员会推荐一个唯一的键来表示每个对象,但这与set不同,因为您可以得到两个相同的对象,每个对象都有一个唯一的键。Java API通过比较散列代码值(而不是键)来检查重复的值,而且由于Javascript中没有对象的散列代码值表示,因此几乎不可能进行相同的操作。甚至JS库的原型也承认这个缺点,当它说:

"Hash can be thought of as an associative array, binding unique keys to values (which are not necessarily unique)..."

哈希可以被认为是一个关联数组,将唯一键绑定到值(不一定是唯一的)……

http://www.prototypejs.org/api/hash

http://www.prototypejs.org/api/hash

#14


0  

In addition to eyelidlessness's answer, here is a function that returns a reproducible, unique ID for any object:

除了无眼睑的答案之外,这里还有一个函数,它为任何对象返回可重复的唯一ID:

var uniqueIdList = [];
function getConstantUniqueIdFor(element) {
    // HACK, using a list results in O(n), but how do we hash e.g. a DOM node?
    if (uniqueIdList.indexOf(element) <0) {
        uniqueIdList.push(element);
    }
    return uniqueIdList.indexOf(element);
}

As you can see it uses a list for look-up which is very inefficient, however that's the best I could find for now.

正如你看到的,它使用了一个查找列表,这是非常低效的,但是这是我目前能找到的最好的。

#15


0  

If you want to use objects as keys you need to overwrite their toString Method, as some already mentioned here. The hash functions that were used are all fine, but they only work for the same objects not for equal objects.

如果想使用对象作为键,需要覆盖它们的toString方法,这里已经提到了一些方法。使用的散列函数都很好,但是它们只适用于相同的对象,而不适用于相同的对象。

I've written a small library that creates hashes from objects, which you can easily use for this purpose. The objects can even have a different order, the hashes will be the same. Internally you can use different types for your hash (djb2, md5, sha1, sha256, sha512, ripemd160).

我编写了一个小的库,它从对象创建散列,您可以很容易地为此目的使用它。对象甚至可以有不同的顺序,散列将是相同的。在内部,您可以对哈希使用不同的类型(djb2、md5、sha1、sha256、sha512、ripemd160)。

Here is a small example from the documentation:

以下是文件中的一个小例子:

var hash = require('es-hash');

// Save data in an object with an object as a key
Object.prototype.toString = function () {
    return '[object Object #'+hash(this)+']';
}

var foo = {};

foo[{bar: 'foo'}] = 'foo';

/*
 * Output:
 *  foo
 *  undefined
 */
console.log(foo[{bar: 'foo'}]);
console.log(foo[{}]);

The package can be used either in browser and in Node-Js.

该包可以在浏览器和Node-Js中使用。

Repository: https://bitbucket.org/tehrengruber/es-js-hash

库:https://bitbucket.org/tehrengruber/es-js-hash

#16


0  

If you want to have unique values in a lookup object you can do something like this:

如果你想在一个查找对象中有唯一的值,你可以这样做:

Creating a lookup object

创建一个查询对象

var lookup = {};

Setting up the hashcode function

设置hashcode函数

function getHashCode(obj) {
    var hashCode = '';
    if (typeof obj !== 'object')
        return hashCode + obj;
    for (var prop in obj) // No hasOwnProperty needed
        hashCode += prop + getHashCode(obj[prop]); // Add key + value to the result string
    return hashCode;
}

Object

对象

var key = getHashCode({ 1: 3, 3: 7 });
// key = '1337'
lookup[key] = true;

Array

数组

var key = getHashCode([1, 3, 3, 7]);
// key = '01132337'
lookup[key] = true;

Other types

其他类型

var key = getHashCode('StackOverflow');
// key = 'StackOverflow'
lookup[key] = true;

Final result

最终结果

{ 1337: true, 01132337: true, StackOverflow: true }

{1337:true, StackOverflow: true}

Do note that getHashCode doesn't return any value when the object or array is empty

请注意,当对象或数组为空时,getHashCode不会返回任何值

getHashCode([{},{},{}]);
// '012'
getHashCode([[],[],[]]);
// '012'

This is similar to @ijmacd solution only getHashCode doesn't has the JSON dependency.

这类似于@ijmacd解决方案,只有getHashCode没有JSON依赖项。


推荐阅读
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • 模板引擎StringTemplate的使用方法和特点
    本文介绍了模板引擎StringTemplate的使用方法和特点,包括强制Model和View的分离、Lazy-Evaluation、Recursive enable等。同时,还介绍了StringTemplate语法中的属性和普通字符的使用方法,并提供了向模板填充属性的示例代码。 ... [详细]
  • Java程序设计第4周学习总结及注释应用的开发笔记
    本文由编程笔记#小编为大家整理,主要介绍了201521123087《Java程序设计》第4周学习总结相关的知识,包括注释的应用和使用类的注释与方法的注释进行注释的方法,并在Eclipse中查看。摘要内容大约为150字,提供了一定的参考价值。 ... [详细]
  • HashMap的相关问题及其底层数据结构和操作流程
    本文介绍了关于HashMap的相关问题,包括其底层数据结构、JDK1.7和JDK1.8的差异、红黑树的使用、扩容和树化的条件、退化为链表的情况、索引的计算方法、hashcode和hash()方法的作用、数组容量的选择、Put方法的流程以及并发问题下的操作。文章还提到了扩容死链和数据错乱的问题,并探讨了key的设计要求。对于对Java面试中的HashMap问题感兴趣的读者,本文将为您提供一些有用的技术和经验。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • Android JSON基础,音视频开发进阶指南目录
    Array里面的对象数据是有序的,json字符串最外层是方括号的,方括号:[]解析jsonArray代码try{json字符串最外层是 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • Whatsthedifferencebetweento_aandto_ary?to_a和to_ary有什么区别? ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
  • Iamtryingtocreateanarrayofstructinstanceslikethis:我试图创建一个这样的struct实例数组:letinstallers: ... [详细]
author-avatar
Zhangjingy2502870421
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有