如何从Map返回默认值

How to return a default value from a Map?

本文关键字:返回 默认值 Map      更新时间:2023-09-26

使用ES6 Proxy对象,当普通对象中不存在属性时,可以返回默认值。

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Proxy

如何使用地图进行此操作?我尝试了以下代码,但总是返回默认值:

var map = new Map ([
    [1,  'foo'],  // default
    [2,  'bar'],
    [3,  'baz'],
]);
var mapProxy = new Proxy(map, {
    get: function(target, id) {
        return target.has(id) ? target.get(id) : target.get(1);
    },
});
console.log( mapProxy[3] );  // foo

这是因为映射键是数字,但代理属性名称始终是字符串。您需要先将id强制转换为数字。

工作示例(需要现代JS引擎):

var map = new Map ([
    [1,  'foo'],  // default
    [2,  'bar'],
    [3,  'baz'],
]);
var mapProxy = new Proxy(map, {
    get: function(target, id) {
        // Cast id to number:
        id = +id;
        return target.has(id) ? target.get(id) : target.get(1);
    },
});
console.log( mapProxy[3] ); // baz
console.log( mapProxy[10] ); // foo

写这篇文章的一个好方法是:

const map = new Map ([
    [1,  'foo'],  // default
    [2,  'bar'],
    [3,  'baz'],
]);
const get = (id) => map.get(id) ?? map.get(3);  // 3 as default
console.log(get(1));  // Returns 'foo' as expected
console.log(get(42));  // Defaults to 'baz'

在Scala中,映射是带有getOrElse方法的单子。如果monad(容器)不包含值,则其get方法会异常失败,但getOrElse允许用户编写无误的代码

Map.prototype.getOrElse = function(key, value) {
  return this.has(key) ? this.get(key) : value
}
var map = new Map ([[1,  'foo'],  [2,  'bar'], [3,  'baz']]); 
[map.get(1), map.getOrElse(10, 11)]; // gives 11

另一个选项是扩展您的地图withDefaultValue方法

//a copy of map will have a default value in its get method
Map.prototype.withDefaultValue = function(defaultValue) {
  const result = new Map([...this.entries()]); 
  const getWas = result.get; result.get = (key) => 
    result.has(key) ? getWas.call(this, key) : defaultValue; 
  return result
}
map.withDefaultValue(12).get(10) // gives 12

这就是Scala中的操作方式。或者,至少看起来是这样。