2

I'm tasked with summarizing an array of over 500 other arrays. Here is a sample of some of the entries for var list

var list = [
  [
    "MIKE",               //employee first
    "NGUYEN",             //employee last
    123,                  //id
    "Sandra M.",          //supervisor name 
    "[email protected]"  //supervisor email
  ],
  [
    "MYA",
    "LANE",
    456,
    "John A",
    "[email protected]"
  ],
  [
    "RON",
    "MASTER",
    789,
    "John A",
    "[email protected]"
  ],
  [
    "MIKE",
    "NGUYEN",
    123,
    "Sandra M.",
    "[email protected]"
  ],
  [
    "MYA",
    "LANE",
    456,
    "john A",
    "[email protected]"
  ],
  [
    "ROBERT",
    "RULES",
    100,
    "Sandra M.",
    "[email protected]"
  ],
  [
    "ROBERT",
    "RULES",
    100,
    "Sandra M.",
    "[email protected]"
  ]
]

I think this would be a great candidate for the reduce function but I can't find a way to use it correctly.

I want to create a simple array of {} that summarizes the data into the following:

var result = [
{
  supervisor: "Sandra M.",   //supervisor name   
  email: [email protected], //supervisor email
  employees: 2,              //number of employees supervised by Sandra
  entries: 4                 //total number of items in array with Sandra as the supervisor
},
{
  supervisor: "John A.",     //supervisor name
  email: [email protected],   //supervisor email
  employees: 2,              //number of employees supervised by John
  entries: 3                 //total number of items in array with John as the supervisor
}
]

Here is where I got stuck:

var result= list.reduce(function(all,item){
    all[item[3]] = all[item[3]] || []
    all[item[3]].push({
       supervisor: item[3],
       email: item[4],
       employees: item[2]++,
       entries: item[0]++,
    })
  return all
},{})

1 Answer 1

2

The main difficulty here looks to be differentiating an employee from a (non-employee) entry. It looks like all non-employee entry items have 6 items in an input array (including a value for the month), whereas the employees do not have a month. This can be identified pretty easily by checking the length of what you're iterating over.

Reduce into an object indexed by the supervisor email, creating an object at that point if it doesn't exist beforehand. Then, if the item you're iterating over is an employee, increment the employees property (and increment the entries property regardless).

var list = [
  [
    "MIKE",               //employee first
    "NGUYEN",             //employee last
    123,                  //id
    "Sandra M.",          //supervisor name 
    "[email protected]"  //supervisor email
  ],
  [
    "MYA",
    "LANE",
    456,
    "John A",
    "[email protected]"
  ],
  [
    "RON",
    "MASTER",
    789,
    "John A",
    "[email protected]"
  ],
  [
    "MIKE",
    "NGUYEN",
    123,
    "Sandra M.",
    "[email protected]"
  ],
  [
    "MYA",
    "LANE",
    456,
    "February",
    "john A",
    "[email protected]"
  ],
  [
    "ROBERT",
    "RULES",
    100,
    "March",
    "Sandra M.",
    "[email protected]"
  ],
  [
    "ROBERT",
    "RULES",
    100,
    "March",
    "Sandra M.",
    "[email protected]"
  ]
]

var resultObj = list.reduce(function(all,item){
    const isEmployee = item.length === 5;
    const [supervisor, email] = item.slice(-2);
    if (!all[email]) {
      all[email] = { supervisor, email, employees: 0, entries: 0 };
    }
    if (isEmployee) {
      all[email].employees++;
    }
    all[email].entries++;
    
  return all
},{});
const result = Object.values(resultObj);
console.log(result);

For the new data structure, make a Set of the ids that have been counted as employees. If an item you're iterating over is included in that Set, don't add to the employees count:

var list = [
  [
    "MIKE",               //employee first
    "NGUYEN",             //employee last
    123,                  //id
    "Sandra M.",          //supervisor name 
    "[email protected]"  //supervisor email
  ],
  [
    "MYA",
    "LANE",
    456,
    "John A",
    "[email protected]"
  ],
  [
    "RON",
    "MASTER",
    789,
    "John A",
    "[email protected]"
  ],
  [
    "MIKE",
    "NGUYEN",
    123,
    "Sandra M.",
    "[email protected]"
  ],
  [
    "MYA",
    "LANE",
    456,
    "john A",
    "[email protected]"
  ],
  [
    "ROBERT",
    "RULES",
    100,
    "Sandra M.",
    "[email protected]"
  ],
  [
    "ROBERT",
    "RULES",
    100,
    "Sandra M.",
    "[email protected]"
  ]
]

const seenIds = new Set();
var resultObj = list.reduce(function(all,item){
    const [id, supervisor, email] = item.slice(-3);
    if (!all[email]) {
      all[email] = { supervisor, email, employees: 0, entries: 0 };
    }
    if (!seenIds.has(id)) {
      all[email].employees++;
      seenIds.add(id);
    }
    all[email].entries++;
    
  return all
},{});
const result = Object.values(resultObj);
console.log(result);

Sign up to request clarification or add additional context in comments.

5 Comments

Thank you! i actually meant to delete the month values for the employees. I have updated the sample array. Let me know if this requires modification as well.
But now, without the months, how can you distinguish between someone who is an employee, vs someone who is only an entry? What is the logic?
every item in the array is an entry. An employee would be each unique individual in the array. For example for employee Robert Rules, there are two entries because he shows up twice. Sorry for the confusion.
just to clarify some more, I'm trying to sum up all the entries (i.e. array items) with the same supervisor, and for sum the the unique employees assigned to the supervisor regardless of how many times they show up in the array list. I hope that doesn't cause more confusion.
It looks like the IDs are repeated when there's a repeat user, so you can use a Set to keep track of which ones have already been counted as employees - see edit

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.