Reputation: 3841
I'm trying to convert an array of objects into a hashmap. I only have some parts of ES6 available and I cannot use Map
as well.
The objects in the array are quite simple, e.g. {nation: {name: string, iso: string, scoringPoints: number}
. I need to sort them by scoringPoints
.
I want now a "dictionary" holding the rank by iso -> {[iso:string]:number}
.
I already tried (from here (SO))
const dict = sortedData.reduce((prev, curr, index, array) => (
{ ...array, [curr.nation.iso]: ++index }
), {});
But dict
turns out to be an Object
with indices starting with 0
. Hopefully there is just a small thing I don't see. But currently my head is spinning how to convert a simple array into a hashmap-like object.
Maybe Array.map
?
I should also note that I am using TypeScript
which I also had some trouble before when not typed correctly.
const test = [
{ nation: { name: "Germany", iso: "DE", rankingPoints: 293949 } },
{ nation: { name: "Hungary", iso: "HU", rankingPoints: 564161 } },
{ nation: { name: "Serbia", iso: "SR", rankingPoints: 231651 } }
];
const sorted = test.sort((a, b) => a.nation.rankingPoints - b.nation.rankingPoints);
const dict = sorted.reduce((prev, curr, index, array) => ({ ...array, [curr.nation.iso]: ++index }), {});
console.log(JSON.stringify(dict));
is showing
{
"0": {
"nation": {
"name": "Serbia",
"iso": "RS",
"rankingPoints": 231651
}
},
"1": {
"nation": {
"name": "Germany",
"iso": "DE",
"rankingPoints": 293949
}
},
"2": {
"nation": {
"name": "Hungary",
"iso": "HU",
"rankingPoints": 564161
}
},
"HU": 3
}
in the console.
As per comments, what I want is a hashmap-like object like
{
"HU": 1,
"DE": 2,
"RS": 3
}
where the property-value is the rank (+1) in the sorted data so I can simply get the rank by accessing dict["DE"]
which would return 2
.
Upvotes: 17
Views: 54359
Reputation: 5605
It is also possible to achieve this using Array.map and Object.fromEntries:
const test = [
{ nation: { name: "Germany", iso: "DE", rankingPoints: 293949 } },
{ nation: { name: "Hungary", iso: "HU", rankingPoints: 564161 } },
{ nation: { name: "Serbia", iso: "SR", rankingPoints: 231651 } }
];
const sorted = test.sort((a, b) => a.nation.rankingPoints < b.nation.rankingPoints ? 1 : (a.nation.rankingPoints > b.nation.rankingPoints ? -1 : 0));
const dict = Object.fromEntries(sorted.map((c, index) => [c.nation.iso, index + 1]));
console.log(dict);
Upvotes: 6
Reputation: 36
const test = [
{ nation: { name: "Germany", iso: "DE", rankingPoints: 293949 } },
{ nation: { name: "Hungary", iso: "HU", rankingPoints: 564161 } },
{ nation: { name: "Serbia", iso: "SR", rankingPoints: 231651 } }
];
const sorted = test.sort((a, b) => b.nation.rankingPoints - a.nation.rankingPoints);
const dict = sorted.reduce((result, curr, index, array) => ({ ...result, [curr.nation.iso]: ++index }), {});
console.log(JSON.stringify(dict));
Upvotes: 0
Reputation: 51894
Capture the position of each key in your data using forEach
or reduce
:
const test = [
{ nation: { name: "Germany", iso: "DE", rankingPoints: 293949 } },
{ nation: { name: "Hungary", iso: "HU", rankingPoints: 564161 } },
{ nation: { name: "Serbia", iso: "SR", rankingPoints: 231651 } }
];
const sorted = test.sort((a, b) => a.nation.rankingPoints - b.nation.rankingPoints);
// Using forEach:
var dict = {}
sorted.forEach((el, index) => dict[el.nation.iso] = sorted.length - index);
// Using reduce:
dict = sorted.reduce(
(dict, el, index) => (dict[el.nation.iso] = sorted.length - index, dict),
{}
);
console.log(dict)
console.log("dict['DE'] = ", dict['DE'])
Output:
{
"SR": 3,
"DE": 2,
"HU": 1
}
dict['DE'] = 2
(Note the order of properties is not significant in an object used as a map - if you need a specific order use an array.)
Upvotes: 22