Could anyone help me with below logic implementation. I am new to Javascript and have been practicing advanced functions. The below code does the job but is there a better way to achieve the same? I want to make my code perfect.
I am grouping by location and then getting the sentiments count.
// Feedback
const sentiments = [
{ location: "France", sentiment: "dissatisfied" },
{ location: "France", sentiment: "happy" },
{ location: "France", sentiment: "happy" },
{ location: "Germany", sentiment: "happy" },
{ location: "France", sentiment: "sad" },
{ location: "Germany", sentiment: "sad" },
{ location: "Germany", sentiment: "happy" },
{ location: "Germany", sentiment: "happy" },
{ location: "Germany", sentiment: "sad" },
{ location: "Germany", sentiment: "dissatisfied" },
{ location: "Spain", sentiment: "dissatisfied" },
{ location: "Spain", sentiment: "happy" },
{ location: "Spain", sentiment: "happy" },
];
// Group by Sentiments
function GroupBySentiments(location, acc, cvalue) {
let key = cvalue["sentiment"];
// first time 0th index will be empty, so insert the sentiment
if (acc[location][0] == undefined) {
acc[location].push({ [key]: 1 });
} else if (acc[location].findIndex((l) => l.hasOwnProperty(key)) == -1) {
acc[location].push({ [key]: 1 });
} else {
let index = acc[location].findIndex((l) => l.hasOwnProperty(key));
acc[location][index][key] += 1;
}
return acc;
}
//Group by location
result = sentiments.reduce((acc, sentiment) => {
let key = sentiment["location"];
if (!acc[key]) {
acc[key] = [];
}
return GroupBySentiments(key, acc, sentiment);
}, {});
//OUTPUT
{
France: [ { dissatisfied: 1 }, { happy: 2 }, { sad: 1 } ],
Germany: [ { happy: 3 }, { sad: 2 }, { dissatisfied: 1 } ],
Spain: [ { dissatisfied: 1 }, { happy: 2 } ]
}
-
1\$\begingroup\$ Welcome to Code Review! Please edit your question so that the title describes the purpose of the code, rather than its mechanism. We really need to understand the motivational context to give good reviews. Thanks! \$\endgroup\$Toby Speight– Toby Speight2021年06月05日 11:13:12 +00:00Commented Jun 5, 2021 at 11:13
1 Answer 1
Output format
For each location, you have a list of objects with a single sentiment.
i.e.: { France: [ { dissatisfied: 1 }, { happy: 2 }, ... ] }
To access how many are "happy" from France you would need to do something like
const happySentiment = results.France.find((sentiment) => sentiment.hasOwnProperty("happy"));
const happyCount = happySentiment ? happySentiment.happy : 0;
This is, imo, a lot of work just to find how many people are happy in France, at this point you might as well add +1 to dissatisfied for me.
Joke aside, if there is not a specific reason to work with that output format, why not generate something that is easier to handle?
i.e.: { France: { dissatisfied: 1, happy: 2 }}
and thus to access the same result as before would be:
const happyCount = results.France.happy ?? 0;
New Implementation
const sentiments = [
{ location: "France", sentiment: "dissatisfied" },
{ location: "France", sentiment: "happy" },
{ location: "France", sentiment: "happy" },
{ location: "Germany", sentiment: "happy" },
{ location: "France", sentiment: "sad" },
{ location: "Germany", sentiment: "sad" },
{ location: "Germany", sentiment: "happy" },
{ location: "Germany", sentiment: "happy" },
{ location: "Germany", sentiment: "sad" },
{ location: "Germany", sentiment: "dissatisfied" },
{ location: "Spain", sentiment: "dissatisfied" },
{ location: "Spain", sentiment: "happy" },
{ location: "Spain", sentiment: "happy" },
];
const result = sentiments.reduce((acc, {location, sentiment}) => {
const sentimentCounts = acc[location] ?? {};
sentimentCounts[sentiment] = (sentimentCounts[sentiment] ?? 0) + 1;
acc[location] = sentimentCounts;
return acc;
}, {});
console.log(result);
-
\$\begingroup\$ I appreciate this, Very nice solution! many thanks \$\endgroup\$user3416431– user34164312021年06月05日 14:06:04 +00:00Commented Jun 5, 2021 at 14:06
-
\$\begingroup\$ One option depending on your needs is just counting in the original array
(loc, sent) => sentiments.filter(s => s.location == loc && s.sentiment == sent).length
. Considered making this an answer, but it's more of a "for completeness" addition \$\endgroup\$JollyJoker– JollyJoker2021年06月05日 14:24:36 +00:00Commented Jun 5, 2021 at 14:24