0

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?

3 Answers 3

3

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; 
}, {});
Sign up to request clarification or add additional context in comments.

1 Comment

Exactly what I needed. Thank you for the detailed response. Helped me understand the solution a lot as well.
0

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;
        }, []);
    }

1 Comment

This creates a nested array, but typically when grouping by a property you want to be able to get all the records by passing a property value, i.e. in an object hashed on the property value.
-1

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);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.