Serdar Mustafa
Serdar Mustafa

Reputation: 935

loop and map through objects in array and group by value

I am trying to group campaigns in my data by the sales person that created created them but keep going around in circles with different JS array methods.

I have filtered my main data set to return those that have the user role of sales person.

I have my campaign data that shows who created the campaigns

I now have to to group them by sales person.

In my mind I saw it as loop/map through each campaign object in campaigns array, check the createdBy name and return a new array of objects that have the results group by createdBy name.

Sounded easy in my head but can't get around it.

I have put together the following:

  const filtered = usersData.filter((val) => val.role === 'sales');
// this returns only the sales people out of all the possible user roles in the following format: 
 
active: true
createdAt: "2019-04-11T21:00:00.000Z"
email: "[email protected]"
name: "Alexander Tom Jones"
phone: 3044283743
role: "sales"
_id: "5c8a20d32f8fb814b56fa187"

// my campaign data contains the name of the sales person:

budget: 57154564
company: "sales company"
createdAt: "2020-07-30T09:03:51.925Z"
createdBy: "sales user"
creator_id: "5f228c8d58769fc7d556a6fa"
endDate: "2020-11-08T00:00:00.000Z"
isDeleted: false
location: "Helsinki"
name: "sales test campaign"


// with this function I can return all of the campaigns created by a sales person 1 by 1:

const filteredCampaigns = campaignData.filter(
    (val) => val.createdBy === 'sales user'
  );

I just cant figure out how to "loop" through each sales person.

I have looked at map / reduce and groupby solutions but nothing comes remotely close. Where am I going wrong?

Upvotes: 0

Views: 379

Answers (3)

Gerard
Gerard

Reputation: 15796

Assuming your array contains objects, you can use the filter functionality.

const campaignData = [{
    budget: 57154564,
    company: "sales company",
    createdAt: "2020-07-30T09:03:51.925Z",
    createdBy: "sales user",
    creator_id: "5f228c8d58769fc7d556a6fa",
    endDate: "2020-11-08T00:00:00.000Z",
    isDeleted: false,
    location: "Helsinki",
    name: "sales test campaign"
  },
  {
    budget: 10,
    company: "sales company",
    createdAt: "2020-07-29T09:03:51.925Z",
    createdBy: "buy user",
    creator_id: "5f228c8d58769fc7d556a6fb",
    endDate: "2020-12-08T00:00:00.000Z",
    isDeleted: false,
    location: "Stockholm",
    name: "sales test campaign"
  }
];

const filteredCampaigns = campaignData.filter(
  function(item) {
    return item.createdBy == 'sales user';
  }
);

console.log(filteredCampaigns);

Upvotes: -1

Jared Smith
Jared Smith

Reputation: 22050

For grouping by a property, you typically want to use Array.prototype.reduce in a pattern like so:

const bySalesPerson = campaignData.reduce((records, record) => {
  // get the property to group by, replace with the
  // actual property name you want (createdBy?)
  const { salesPerson } = record;

  // check if it exists in our accumulator object, if not
  // assign empty array
  if (!(salesPerson in records)) records[salesPerson] = [];

  // push current record into the array associated with
  // that value of the property, in this case a particular
  // sales person
  records[salesPerson].push(record);

  // return the accumulator object from the callback
  return records; 
}, {});

Upvotes: 3

Yogendra Chauhan
Yogendra Chauhan

Reputation: 825

You can use this method to group by sales user. Just call this method like this: const grouped = groupBy(campaignData, ['createdBy']);

groupBy(xs, key) {
        return xs.reduce((rv, x) => {
            const v = x[key];
            const el = rv.find((r) => r && r.key === v);
            if (el) {
                el.values.push(x);
            } else {
                rv.push({
                    key: v,
                    values: [x]
                });
            }
            return rv;
        }, []);
    }

Upvotes: 0

Related Questions