Home > Mobile >  Create a JavaScript array of objects group and sum items
Create a JavaScript array of objects group and sum items

Time:10-20

I have an array of company reviews like below, and from that, I am trying to generate three new arrays. I have managed to create two arrays with sums but the last one(rating filter) is where I got stuck, want to create an array for the ratings with 5 items like 1 star, 2 stars, and so on.

const reviews = [
   {
        designation_id: 544,
        designation: 'Software Developer',
        department_id: 18,
        department: 'IT & Information Security',
        overall_rating: 4
    },
    {
        designation_id: 592,
        designation: 'UI Designer',
        department_id: 37,
        department: 'UX, Design & Architecture',
        overall_rating: 5
    },
    {
        designation_id: 544,
        designation: 'Software Developer',
        department_id: 18,
        department: 'IT & Information Security',
        overall_rating: 3.8
    }
]

The desired Output:

const ratingFilter = [
    {count: 2, name: '1 Star'}, 
    {count: 1, name: '2 Stars'},
    {count: 3, name: '3 Stars'},
    {count: 1, name: '4 Stars'},
    {count: 2, name: '5 Stars'}, 
]

This is what I have done so far:

const departmentFilters = [];
const designationFilters = [];

arr.reduce((accu: { [key: string]: any }, curr) => {
    const departmentKey = curr.department
        .split(' ')
        .join('_')
        .toLowerCase();

    const designationKey = curr.designation
        .split(' ')
        .join('_')
        .toLowerCase();

    //departments filters
    if (!accu[departmentKey]) {
        accu[departmentKey] = {
            count: 1,
            name: curr.department,
            id: curr.department_id
        };
            departmentFilters.push(accu[departmentKey]);
        } else {
            accu[departmentKey].count  ;
        }

        //desinations filters
        if (!accu[designationKey]) {
            accu[designationKey] = {
                count: 1,
                name: curr.designation,
                id: curr.designation_id
            };
            designationFilters.push(accu[designationKey]);
        } else {
            accu[designationKey].count  ;
        }

        return accu;
}, Object.create(null));

CodePudding user response:

Here is how I'd do it (assuming I'm understanding your question correctly).

const reviews = [{
    designation_id: 544,
    designation: 'Software Developer',
    department_id: 18,
    department: 'IT & Information Security',
    overall_rating: 4
}, {
    designation_id: 592,
    designation: 'UI Designer',
    department_id: 37,
    department: 'UX, Design & Architecture',
    overall_rating: 5
}, {
    designation_id: 544,
    designation: 'Software Developer',
    department_id: 18,
    department: 'IT & Information Security',
    overall_rating: 3.8
}];

const reviewCountByOverallRating = {};
for (let review of reviews) {
    const overallRating = review.overall_rating; //or perhaps Math.round(review.overall_rating) if you want whole numbers only
    reviewCountByOverallRating[overallRating] = reviewCountByOverallRating[overallRating] || 0;
    reviewCountByOverallRating[overallRating]  ;
}

const ratingFilter = [];
for (let overallRating in reviewCountByOverallRating) {
    const reviewCount = reviewCountByOverallRating[overallRating];
    ratingFilter.push({
        count: reviewCount,
        name: `${overallRating} Star${overallRating === 1 ? '' : 's'}`
    });
}

console.log(ratingFilter);

CodePudding user response:

You can simply achieve this by using Array.reduce() method.

Live Demo :

const reviews = [{
    designation_id: 544,
    designation: 'Software Developer',
    department_id: 18,
    department: 'IT & Information Security',
    overall_rating: 4
}, {
    designation_id: 592,
    designation: 'UI Designer',
    department_id: 37,
    department: 'UX, Design & Architecture',
    overall_rating: 5
}, {
    designation_id: 544,
    designation: 'Software Developer',
    department_id: 18,
    department: 'IT & Information Security',
    overall_rating: 3.8
}];

let res = reviews.reduce((acc, curr) => {
  if (!curr.count) curr.count = 1
  if (!acc.some(({ rating }) => rating == curr.overall_rating)) {
    acc.push({
        rating: curr.overall_rating,
      count: curr.count
    });
  } else {
    acc.find(({ rating }) => rating == curr.overall_rating).count  ;
  }
  return acc;
}, []);

console.log(res);

  • Related