如何在 JavaScript/TypeScript 中创建具有非唯一键的地图?

Posted

技术标签:

【中文标题】如何在 JavaScript/TypeScript 中创建具有非唯一键的地图?【英文标题】:How can I create a Map with non-unique keys in JavaScript/TypeScript? 【发布时间】:2019-04-11 12:33:29 【问题描述】:

为了与现有代码交互,我希望在 javascript/TypeScript 中实现一个带有非唯一键的 Map(对于 Angular 中的网络应用程序)。

我知道 JavaScript/TypeScript 中的地图强制使用唯一键。如何实现“非唯一”地图?

创建键值对象数组不起作用,因为该结构不会以现有消费者代码的正确形状从 JSON 反序列化。

例如,我希望创建类似以下结构的东西:

vehicleOptions : NonUniqueMap<key: string, value: color: string, isTowingCapable: boolean>

  "Truck",  "Red", true ,
  "Compact Sedan",  "Black", false ,
  "Compact Sedan",  "Blue", false 

【问题讨论】:

使用包含对象的数组,例如 label: 'Truck', obj: ... 。请注意,您当前的 "Red", true 语法无效,键值对需要用冒号分隔,而不是逗号 为什么不使用Array呢? 不清楚你将如何使用这个数据结构。例如,当您在对象上使用密钥 Compact Sedan 时,为什么期望返回? 【参考方案1】:

你可以在这里滥用 JS 的 Pass By Reference 特性。对象通过引用传递,因此具有相同属性的两个不同对象仍然是唯一的。 考虑下面的例子:

function function_key(a,b)
this.a = a;
this.b = b;

function function_val(c,d,e)
this.c = c;
this.d = d;
this.e = e;

var myMapName = new Map();
myMapName.set(new function_key('a','b'),new function_val('c','d','e'));
myMapName.set(new function_key('a','b'),new function_val('c','d','e'));
myMapName.set(new function_key('a','b'),new function_val('c','d','e'));
myMapName.set(new function_key('a','b'),new function_val('c','d','e'));
myMapName.set(new function_key('a','b'),new function_val('c','d','e'));
console.log(myMapName);

Map seems DRUNK

【讨论】:

【参考方案2】:

您还可以使用此函数创建具有列表值的 uniqMap:

function getBucketMap<T>(array: T[], uniqueProperty: string = 'id'): Map<any, T[]> 
    return array
    .filter(value => value)
    .reduce((bucketMap: Map<any, T[]>, item: T) => 
        const list = [item];

        if (bucketMap.has(item[uniqueProperty])) 
            list.push(...bucketMap.get(item[uniqueProperty]));
        
        bucketMap.set(item[uniqueProperty], list);

        return bucketMap;

     , new Map<any, T[]>());

所以你可以像这样传递一个汽车数组并传递和 uniq 属性:

const cars = [
  
    type: 'Truck',
    info: 
        'black': true
     
  ,
  
    type: 'Truck',
    info: 
        'black': true
     
  ,
  
    type: 'Compact Sedan',
    info: 
        'blue': false
     
  ,
];

const carsMap = getBucketMap(cars, 'type');

【讨论】:

【参考方案3】:

你不能。

您可以创建独特的地图。 当您有两个相同的密钥时,您可以将其存储为:

const map = 
    "Truck": [ "Red": true ],
    "Compact Sedan": [ "Black": false ,  "Blue": false ]

然后,当你得到Compact Sedan 的值时,你得到一个数组。

所以你可以得到第一个/第二个值:

map["Compact Sedan"][0]; //  "Black": false 
map["Compact Sedan"][1]; //  "Blue": false 

【讨论】:

以上是关于如何在 JavaScript/TypeScript 中创建具有非唯一键的地图?的主要内容,如果未能解决你的问题,请参考以下文章

如何在单独的非 Vue 组件、JavaScript/TypeScript 文件中访问 Vuex 状态?

如何在 javascript/typescript 事件回调中访问它,同时保留 removeEventListener 的能力? [复制]

Javascript/Typescript 中类的交叉引用如何工作?

如何在JavaScript / TypeScript中等待Promise列表?

如何从 javascript/typescript 模块文件(导入/导出)访问 Vuex 商店?

如何通过 javascript/typescript 获取“事件”对象的特定元素