覆盖JavaScript映射的相等函数

时间:2018-10-29 18:03:17

标签: javascript dictionary

我想用Javascript创建一个Map(字典),它们的键是数字数组,值是某个对象。我想从地图中检索以前使用相同数组内容存储的值-即,如果我有一个包含某些内容的数组,我想检索先前存储用于具有相同内容的数组的值(如果有)。

在大多数其他语言中,这很容易。您将重写Map的equals函数,以便测试具有相同内容的两个数组相等。这似乎不是可用的Javascript。映射键正在使用SameValueZero进行测试,如果它们是同一对象,则它们仅将两个对象视为相等。

有没有一种方法可以覆盖平等,或者有另一种标准的方法可以用Javascript处理这种情况?

2 个答案:

答案 0 :(得分:0)

您可以使用Proxy更改访问对象属性(也意味着数组元素)的方式。它们允许您拦截带有回调的属性获取和设置。

这是一个代理数组的示例,该数组仅存储两个元素,并且无论您要什么索引,都将返回这两个元素之一。

    const arr = new Proxy([], {
      get: function(self, prop) {
        const index = parseInt(prop, 10)
        // If the property is not a number, then no special handling
        if (isNaN(index)) {
          return self[prop]
        }
        
        if (index % 2 === 0) {
          // even
          return self[0]
        } else {
          // odd
          return self[1]
        }
      }
    })
    
    // Add just two elements
    arr.push('even')
    arr.push('odd')
    
    // Get any index
    console.log(arr[0]) // even
    console.log(arr[1]) // odd
    console.log(arr[2]) // even
    console.log(arr[301]) // odd


或者,您可以编写自己的类,该类不依赖于拦截基本运算符的“魔术”,而只拥有get(key)set(key, value)方法来使用所需的任何逻辑。

答案 1 :(得分:0)

如果您不需要Map的特殊功能(对插入顺序的值进行内置迭代),则所需的相等函数可以通过比较数组的toString()值来工作,您可以使用标准对象:

const notReallyAMap = {};
notReallyAMap[[0, 1, 2]] = 'whole';
notReallyAMap[[0.5, 2.75, 6.125]] = 'rational';
notReallyAMap[[1, 2, 3, 4, 5]] = 'my luggage';

const testArray = [1, 2, 3, 4, 5];
console.log(notReallyAMap[testArray]);