Zividivi
Zividivi

Reputation: 1

Count JSON by two properties in javascript

I have been trying without success to count activity per user to find sum of the same activity made by the same user throughout the days.

data = [ {day: "2021-01-05", user: "1", activity: "1"}
,{day: "2021-01-05", user: "2", activity: "2"}
,{day: "2021-01-05", user: "1", activity: "2"}
,{day: "2021-01-05", user: "1", activity: "3"}
,{day: "2021-01-06", user: "3", activity: "1"}
,{day: "2021-01-06", user: "2", activity: "0"}
,{day: "2021-01-06", user: "3", activity: "2"}
,{day: "2021-01-06", user: "4", activity: "3"}
,{day: "2021-01-07", user: "4", activity: "1"}
,{day: "2021-01-07", user: "2", activity: "0"}
,{day: "2021-01-07", user: "3", activity: "2"}
,{day: "2021-01-07", user: "3", activity: "3"} ]

I want to be able to create a new array of JSONs with user, activity and property of count of this same combination. For example, user 2 and activity 0 will have the property of count: 2

Upvotes: 0

Views: 63

Answers (2)

bricksphd
bricksphd

Reputation: 177

You can loop over the users and activities. In the loop you can filter for all entries that match the current user and activity value. Something like this:

for(let user = 1; user < 5; user++){
  for(let activity = 0; activity <4; activity++){
    let specific = data.filter(i=>i.user == "" + user && i.activity == ""+activity)
    console.log("User " +  user + ", activity " + activity + ", count " + specific.length)
  }
}

If you want to get the same result without hardcoding the number of users and activities, you can find the set of users and activities using map reduce:

let userList = data.map(i => i.user).reduce((a, b) => {
  if (!a.includes(b))
    a.push(b)
  return a;
}, [])

let activityList = data.map(i => i.activity).reduce((a, b) => {
  if (!a.includes(b))
    a.push(b)
  return a;
}, [])

for (let user of userList) {
  for (let activity of activityList) {
    let specific = data.filter(i => i.user == "" + user && i.activity == "" + activity)
    console.log("User " + user + ", activity " + activity + ", count " + specific.length)
  }
}

Upvotes: 0

Wazeed
Wazeed

Reputation: 1280

This is one of approach using reduce method of Array.

const data = [
    { day: "2021-01-05", user: "1", activity: "1" }
    , { day: "2021-01-05", user: "2", activity: "2" }
    , { day: "2021-01-05", user: "1", activity: "2" }
    , { day: "2021-01-05", user: "1", activity: "3" }
    , { day: "2021-01-06", user: "3", activity: "1" }
    , { day: "2021-01-06", user: "2", activity: "0" }
    , { day: "2021-01-06", user: "3", activity: "2" }
    , { day: "2021-01-06", user: "4", activity: "3" }
    , { day: "2021-01-07", user: "4", activity: "1" }
    , { day: "2021-01-07", user: "2", activity: "0" }
    , { day: "2021-01-07", user: "3", activity: "2" }
    , { day: "2021-01-07", user: "3", activity: "3" }
];

// Calculate user activity count
const activityByUser = data.reduce((op, { user, activity }) => {
    const key = `${user}-${activity}`, { result, index } = op;
    if (index.hasOwnProperty(key)) {
        result[index[key]].count++;
    } else {
        index[key] = result.length;
        result.push({ user, activity, count: 1 })
    }
    return op;
}, { result: [], index: {} }).result;

console.log(activityByUser);

Upvotes: 1

Related Questions