如何在JavaScript / TypeScript中使用非唯一键创建Map?

时间:2018-11-08 01:28:52

标签: javascript arrays angular typescript dictionary

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

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

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

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

vehicleOptions : NonUniqueMap<key: string, value: {color: string, isTowingCapable: boolean}>
{
  "Truck", { "Red", true },
  "Compact Sedan", { "Black", false },
  "Compact Sedan", { "Blue", false }
}

3 个答案:

答案 0 :(得分:5)

你不能。

您可以创建一个唯一的地图。 当您拥有两个相同的键时,可以将其存储为:

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 }

答案 1 :(得分:0)

您还可以使用此功能来创建具有列表值的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');

答案 2 :(得分:0)

您可以在此处滥用JS的“通过引用传递”功能。对象是通过引用传递的,因此具有相同属性的两个不同对象仍然是唯一的。 考虑以下示例:

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