Return only the most popular spelling of object property in array along with sum of all spellings in descending order

Viewed 30

The _id property represents a hashtag entry. I'm trying to return trending hashtags with only the most popular spelling, along with the total of all spellings. The problem is, I was unable to build a mongodb query that returns in the desired format. So I'm having to do some after-the-fact manipulation of the data.

You can see an example snippet of the original query data in the code snippet below.

Here's what the desired output would look like:

[
    { _id: 'FunSnow', tagCount: 15 },
    { _id: 'fukr', tagCount: 12 },
    { _id: 'MyGuns', tagCount: 9 },
    { _id: 'Reviwa', tagCount: 9 },
    { _id: 'whippy', tagCount: 9 },
    { _id: 'fu', tagCount: 1 } 
]

This is as close as I could get so far. Any help much appreciated!

const tagdata = [ 
    { _id: 'fukr', tagCount: 12 },
    { _id: 'FunSnow', tagCount: 12 },
    { _id: 'whippy', tagCount: 9 },
    { _id: 'MyGuns', tagCount: 8 },
    { _id: 'Reviwa', tagCount: 7 },
    { _id: 'Funsnow', tagCount: 2 },
    { _id: 'reviwa', tagCount: 2 },
    { _id: 'myguns', tagCount: 1 },
    { _id: 'funsnow', tagCount: 1 },
    { _id: 'fu', tagCount: 1 } 
];

var returnData = [], checkObj = {}, tagCount;

  tagdata.forEach((item, i) => {
    tagCount = 0;
    objKey = String(item._id).toLowerCase();
    if (!checkObj[objKey]) {
        tagCount = item.tagCount;
        checkObj[objKey] = true;

        tagdata.forEach((checkCount) => {
            if (String(checkCount._id).toLowerCase() == objKey) {
                tagCount = tagCount + 1;
            }
        });

        returnData.push({_id: item._id, tagCount: tagCount});
    } 
});

console.log(returnData);

1 Answers

You can use a reduce function to reduce the array to the desired final result.

const result = tagdata.reduce((acc, cur) => {
    const found = acc.find(({ _id }) => (_id.toLowerCase() === cur._id.toLowerCase()));
    if (found) {
        found.tagCount += cur.tagCount;
    }
    else {
        acc.push(cur);
    }
    return acc;
}, []).sort((a, b) => (b.tagCount - a.tagCount));
Related