Reputation: 35
I have created a map that contains a list of products, and the shop closest by that is selling that product, like so:
var products = new Map()
products.set('product_key', {
shop: 'shop_key',
distance: 1.2
})
Now what I would like to do is sort the entire map on the distance property, so that I can list the products by proximity to my location.
I use a map because I also need to go in and be able to find the distance to one specific product using the key.
Upvotes: 2
Views: 227
Reputation: 136276
One way is to have an array of keys sorted by distance:
"use strict";
var products = new Map()
products.set('product_key', {
shop: 'shop_key',
distance: 1.2
})
products.set('product2_key', {
shop: 'shop2_key',
distance: 0.1
})
console.log(products);
var keysByDistance = Array.from(products.keys()).sort((a, b) => products.get(a).distance - products.get(b).distance);
console.log(keysByDistance.map(key => products.get(key)));
Outputs:
Map {
'product_key' => { shop: 'shop_key', distance: 1.2 },
'product2_key' => { shop: 'shop2_key', distance: 0.1 } }
[ { shop: 'shop2_key', distance: 0.1 },
{ shop: 'shop_key', distance: 1.2 } ]
Upvotes: 1
Reputation: 1074425
Map
loops through its entries in insertion order; you can't sort a map, you can only create one in the sorted order you want.
For what you're doing, I'd probably use an array of entries, and then a map mapping strings to the entries that are in the array:
const productList = [
{distance: 1.8, product_key: "one", shop: "shop_key1"},
{distance: 1.2, product_key: "two", shop: "shop_key2"},
{distance: 1.4, product_key: "three", shop: "shop_key3"}
];
productList.sort((a, b) => a.distance - b.distance);
const map = new Map();
productList.forEach(entry => {
map.set(entry.product_key, entry);
});
console.log("List:");
productList.forEach(entry => {
console.log(JSON.stringify(entry));
});
console.log("Product 'two':", map.get("two"));
That allows you to re-sort as necessary.
But again, Map
iterates in insertion order, so you can do it with just a Map
as the endpoint, by inserting the entries in order:
const productList = [
{distance: 1.8, product_key: "one", shop: "shop_key1"},
{distance: 1.2, product_key: "two", shop: "shop_key2"},
{distance: 1.4, product_key: "three", shop: "shop_key3"}
];
productList.sort((a, b) => a.distance - b.distance);
const map = new Map();
productList.forEach(entry => {
map.set(entry.product_key, entry);
});
productList = null; // don't need it anymore
console.log("List:");
for (let entry of map) {
console.log(JSON.stringify(entry));
}
console.log("Product 'two':", map.get("two"));
Upvotes: 1
Reputation: 2686
Move some pieces to an array, the product key and distance, then sort that array. Do the lookup after you sort.
var products = {
p1:300, p2:60, p3:200, p4:1000,
p5:400, p6:600
}
var sortable = [];
for (var x in products)
sortable.push([x, product[x]])
sortable.sort(
function(a, b) {
return a[1] - b[1]
}
)
//Do lookup on the map based on first elements in sorted array
Upvotes: 0