I’m trying to use reduce to create an object that contains the percentage of presence of various countries in a list.
input:
countriesList = ["US","US","US","UK","IT","IT"]
desidered output:
percCountriesList = [{"country": "US", "weight": 0.5}, {"country": "UK", "weight": 0.1666}, {"country": "IT", "weight": 0.3333}]
How I calculate the percentage:
const countriesList = ["US","US","US","UK","IT","IT"]
const weightPercCountries = countriesList.reduce((pcts, x) => {
pcts[x] = (pcts, (pcts[x] ? pcts[x] : 0) + 100 / countriesList.length);
return pcts;
}, []);
console.log(weightPercCountries)
So, I’ve got the percentages list:
[50, 16.666666666666668, 33.33333333...]
Now, how I can build the desidered output (country + weight) "jsonized"?
Thanks
2
Answers
The code above uses the
??=
operator to set a property if the property is not yet defined, and uses a comma expression to avoid the need for a braced code block ending with withreturn a
.A less compact version of the code is:
First of all, your code produces an empty array (with a few additional properties), because the
x
in your case is a country-shortcut and not an index. So if you dopcts[x] = ..
you are actually doing something likepcts['us'] = ...
which in most cases doesn’t make too much sense for an array.Second, if you want a complex object in you array, you need to create it somewhere … See for instance the following snippet
I defined
reduce
to return anobject
, so I can easily check if the current country (defined byx
) is already contained or not.If it’s not contained, I add a new property to the object, which already holds all properties I want in the result (ie
{ country: x, percentage: 0}
)Now, that I made sure, an object for the current country exists, I can access it via its name and update the percentage. Whether you want
50
or0.5
is up to you. Either use100/countriesList.length
or1/countriesList.length
reduce
now returns an object likeSo to get an array of the values just use
Object.values(...)
which returns all enumerable properties of an object as an arrayOf course you can shorten the callback of the
reduce
(like for instance in Andrew Park’s answer). But for sake of readability (especially for someone who seems to be a beginner) I decided in favour of the more explicit code …