Строка для целочисленного хеширования объектов в JavaScript - PullRequest
0 голосов
/ 28 сентября 2019

В SO есть несколько вопросов, похожих на мой вопрос, но на самом деле ни один из них не отвечает на них полностью.

По сути, я хочу иметь объекты в качестве ключей в JavaScript.Я знаю, что это возможно с Map, однако это не полностью относится к моему сценарию использования.Вот причина:

Допустим, у меня есть два объекта, var d1 = {a: 1, b: 2} и var d2 = {a: 1, b: 2}, и карта var m = new Map().При добавлении d1 к m, когда я позвоню m.get(d2), я получу неопределенное значение.Я предполагаю, что это потому, что Map работает в эталонном порядке.

Однако мне нужна следующая функциональность:

m.set(d1, 'hit');
m.get(d2) // should return 'hit' because properties and values of d1 = d2

Один из подходов, о котором я думал, - не использовать Map, но простой объект JS.Ключи будут JSON.stringify(obj), и когда я хочу получить значение от объекта, я использую JSON.parse(key), а затем выполняю проверку на равенство объектов (Object.getOwnPropertyNames, а затем проверяю по одному).

ОднакоЯ чувствую, что этот подход является более сложным и трудоемким, чем он должен быть.То, что я ищу, - это, вероятно, какая-то хеш-функция, которая бы эффективно отображала объект с ключами типа String на значения типа Number (целое число в моем случае).Кроме того, порядок может быть другим (d1 = {a: 1, b: 2} должен равен d2 = {b: 2, a: 1}).

Как разработать эффективную хеш-функцию для работы с объектами / картами JS для выполнения вышеуказанногоупомянутые операции?

1 Ответ

1 голос
/ 28 сентября 2019

Напишите функцию, которая превращает объект в строку с ключами в согласованном порядке.

function objToKey(obj) {
  Object.keys(obj).sort().map(k => `${k}:${obj[k]}`).join(',');
}

var d1 = {a: 1, b: 2},
  d2 = {b: 2, a: 1},
  m = new Map();

m.set(objToKey(d1), "foo");
console.log(m.get(objToKey(d2)));
...