为了与现有代码交互,我希望在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 }
}
答案 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);