我有一张宣称为var cars = new Map<string, object>();
的地图,其中string
是汽车的型号,object
包含year
和price
等信息
因此,Map
将如下所示:
Map = [
'BMW' => {
id: 123,
price: 2000,
models: {...}
},
'Opel' => {
id: 1234,
price: 3500,
models: {...}
},
....
]
我想通过price
字段(asc或desc)对所有内容进行排序。
我无法找到任何解决方案,因为迭代values
会丢失密钥,而我使用...cars.entries()
阅读的解决方案不适用,因为这些值不可迭代。 / p>
P.S。我目前正在使用TypeScript,但JS的解决方案应该适用。
编辑:我尝试将地图转换为数组,如下所示:
const values = Array.from(this.cars.values());
values.sort((a, b) => {
return (a.price < b.price) ? -1 : 1;
});
但我有一些麻烦重建地图以保持keys
......
答案 0 :(得分:2)
Map
对象迭代并按插入顺序保留其元素。因此,只有您可以创建新的Map
解决方案。我认为最简单的方法是将旧地图转换为数组,对其进行排序并转换为新地图。像这样:
let newMap = new Map([...map].sort(([k, v], [k2, v2])=> {
if (v.price > v2.price) {
return 1;
}
if (v.price < v2.price) {
return -1;
}
return 0;
}));
答案 1 :(得分:0)
地图在插入时间后排序。这就是来龙去脉。如果要对其进行不同的排序,可以构建一个指向地图所使用的相同对象的数组,但具有不同的顺序。要获得Map键,将它直接存储在对象中是有意义的。要设置数组,可以使用插入排序:
const sorted: object[] = [];
for(const [key, car] of cars){
car.name = key;
const insertAt = sorted.findIndex(other => other.price < car.price) + 1;
sorted.splice(insertAt, 0, car);
}
或者你可以事后排序(更短+更慢):
const sorted = [...cars.entries()].map(([name, car]) => ({name, ...car})).sort((a, b) => a.price - b.price);
请注意,如果您只是回归到本机类型,那么使用typescript是没有意义的。您可以改为实现汽车界面,例如:
interface ICar {
price: number;
models: IModel[];
id: number;
name: string;
}
答案 2 :(得分:0)
使用Anton和Jonas中的想法,我得到了这个解决方案。这不是完美的,但似乎有效
private sortCars(cars): Map<string, iCar> {
// Convert the map to array first and sort it by "price"
const carList = Array.from(cars)
.map(([brand, car]) => ({brand, ...car}))
.sort((a, b) => {
if (a.price === b.price) {
return 0;
} else {
return a.price < b.price ? -1 : 1;
}
}
);
// Rebuild the map after sorting it.
const carsMap = new Map();
carList.forEach((car) => carsMap.set(car.name, car));
return carsMap;
}
我选择将品牌名称添加到汽车对象中,以便重新构建最终的地图。相反,我可以在原始地图中搜索对象并返回密钥。