Хеш / ассоциативный массив с использованием нескольких объектов в качестве ключа - PullRequest
1 голос
/ 08 августа 2011

Есть ли способ создать ассоциативный массив, в котором каждый ключ является хешем нескольких объектов? Меня не интересует проверка состояния каждого объекта, а скорее его идентификация.

 var myarray = {};

 var a = new A();
 var b = new B();
 var c = new C();

 // + is not right, but illustrates the hashing I'm after.
 myarray[a + b + c] = 42;

Оператор + неверен. В Java я бы арифметически комбинировал System.identityHashCode() для каждого из этих трех экземпляров и использовал результат, чтобы создать мой новый ключ хеша. Есть ли похожая механика в javascript?

Переопределение метода .toString() в A, B и C не вариант, так как меня интересует идентификация объекта, а не состояние.

Ответы [ 3 ]

3 голосов
/ 08 августа 2011

На самом деле невозможно, поскольку ключи объекта на этом языке могут быть только строками, и нет эквивалента идентичности объекта Java.

: о)

2 голосов
/ 08 августа 2011

Вы можете перезаписать метод toString() прототипов, чтобы создать уникальный хеш для каждого экземпляра. Э.Г.

A.prototype.toString = function() {
    return /* something instance specific here */;
};

Даже a + b + c будет работать тогда.

Обновление: Афаик, вы не можете получить уникальный идентификатор экземпляра (каким бы он ни был) в JavaScript. Однако вы можете назначить каждому экземпляру некоторый идентификатор.

Это работает, только если вы создаете объекты.

1018 * Е.Г. *

var addIdentityTracker = (function() {
    var pad = "0000000000",
        id = 1;

    function generateId() {
         var i = (id++).toString();
         return pad.substr(0, 10 - i.length) + i;
    }

    return function(Constr) {
        var new_constr = function() {
            this.___uid = generateId();
            Constr.apply(this, arguments);
        };
        new_constr.prototype = Constr.prototype;

        new_constr.prototype.toString = function() {
            return this.___uid;
        };

        return new_constr;
     };
}());

и затем сделайте:

A = addIdentityTracker(A);
var a = new A();
1 голос
/ 08 августа 2011

Я бы предложил просто назначить уникальный идентификатор каждому объекту.Javascript не имеет встроенного механизма уникальных идентификаторов, но вы можете назначить уникальный идентификатор любому объекту, который вам нужен, и затем использовать его как таковой.Например, вы можете сделать это:

// getUniqueID is a function that returns a unique ID for any javascript object.
// If no uniqueID is already present on the object, it coins one using a global
// counter and then stores it on the object.
// So that the uniqueID can be combined with other uniqueIDs easily and still
// create a unique union, the uniqueID here is a unique 10 character string.  
// There is no randomness in the IDs as they are only required to be unique 
// within the page, not random or unique in the universe.  The monotomically 
// increasing counter guarantees uniqueness within the page. 

// Two globals we need for generating the unique ID    
var idCntr = 0;
var controlStr = "0000000000";  // 10 digits long

function getUniqueID(o) {
   if (!o.uniqueID) {
       var base = idCntr++ + "";  // get string version of idCntr
       o.uniqueID = controlStr.slice(0, controlStr.length - base.length) + base;  // zero pad
    }
    return(o.uniqueID);
}

var myobj = {};

var a = new A();
var b = new B();
var c = new C();

myobj[getUniqueID(a) + getUniqueID(b) + getUniqueID(c)] = 42;

Чтобы вы могли получить тот же объект в будущем, вам нужно будет снова объединить объекты в правильном порядке.Если это было непросто, то вы можете убедиться в этом и всегда объединять их в числовом порядке с наименьшими первыми числами, чтобы вы всегда получали последовательный порядок.

...