I have been presented with a challenge for javascript. I have an array called arrays. I am trying to compare User A against User B against C. User A, User B and User C are dynamic values and will keep changing.
If date and time of User A and User B and User C are equal, then display output. For e.g., if
var arrays = ['7/10/2021', 'User A', 'Thu', 'even', '09:00 - 09:20'],
['7/10/2021', 'User B', 'Thu', 'even', '09:00 - 09:20'],
['7/10/2021', 'User C', 'Thu', 'even', '09:00 - 09:20'],
['7/10/2021', 'User C', 'Thu', 'even', '10:00 - 10:20'],
then it should show just this.
['7/10/2021', 'Thu', 'even', '09:00 - 09:20'],
My current code is:
var arrays = ['7/10/2021', 'User A', 'Thu', 'even', '09:00 - 09:20'],
['7/10/2021', 'User B', 'Thu', 'even', '09:00 - 09:20'],
['7/10/2021', 'User C', 'Thu', 'even', '09:00 - 09:20'],
['7/10/2021', 'User C', 'Thu', 'even', '10:00 - 10:20']
], result = [];
var frequency = arrays .reduce(function(seen, currentItem) {
if (currentItem in seen) {
seen[currentItem] = seen[currentItem] + 1;
} else {
seen[currentItem] = 1;
}
return seen;
}, {});
for (var key in frequency) {
if (frequency[key] > 1) {
result.push(key.split(",").map(function(currentItem) {
return parseInt(currentItem);
}));
}
}
console.log(result);
My result: []
I tried this
var arrays = [
['7/10/2021', 'User A', 'Thu', 'even', '09:00 - 09:20'],
['7/10/2021', 'User A', 'Thu', 'even', '09:00 - 09:20'],
['7/10/2021', 'User C', 'Thu', 'even', '09:00 - 09:20'],
['7/10/2021', 'User C', 'Thu', 'even', '10:00 - 10:20']];
var myArrayFiltered = arrays.filter(function(item, pos) {
return arrays.indexOf(item) == pos;
});
console.log(myArrayFiltered)
But it display all users which is not I wanted.
I rembember this question from a few hours ago. As you said there, the structure of your data is fixed (ie each row has 5 elements in the same order).
This quick hack below should do what you need. It's probably not the most elegant solution (especially the stringifying and parsing of the array) but it gets the job done.
For explanations see the comments in the code
//this is the index that will be excluded for comparisons
let userindex = 1;
let data = [
['date1', 'user a', 'day 1', 'even', 'time 1'],
['date1', 'user a', 'day 1', 'even', 'time 2'],
['date1', 'user a', 'day 2', 'even', 'time 1'],
['date1', 'user b', 'day 1', 'even', 'time 1'],
['date2', 'user b', 'day 1', 'even', 'time 2'],
['date1', 'user b', 'day 2', 'even', 'time 1'],
['date1', 'user c', 'day 1', 'even', 'time 1'],
['date2', 'user c', 'day 1', 'even', 'time 2'],
['date1', 'user c', 'day 2', 'even', 'time 3'],
]
//get the number of distinct users
let users = data.map(row => row[userindex]) //get the user
.filter((u, i, arr) => arr.indexOf(u) === i) //only get first occurence of each username
.length; //count the elements in the resulting array
//group by different combinations and get users for each distinct combination
let groups = data.reduce((a, row) => {
//remove username from row and stringify the resulting array to use as key in object
let key = JSON.stringify(row.filter((_, i) => i != userindex));
//check if the current combination is already contained in the object, and add if not
if (!a[key]) a[key] = [];
//if the current user isn't contained for the combination add it
if (!a[key].includes(row[userindex])) a[key].push(row[userindex]);
return a;
}, {})
//get only elements which contain all users
let valids = Object.entries(groups) //get an array of [[key, value]] for the group object
.filter(e => e[1].length == users) //filter it for elements which contain all users
.map(e => JSON.parse(e[0])); //parse the key back to an array
console.log(valids)