Reputation: 185
Been going around in circles with this for a while.
For example let's say I have different times slots stored as this
let timechunks1 = [["09:00", "10:00", "11:00"], ["09:00", "10:00", "11:00"], ["09:00", "10:00", "11:00", "12:00"]]
let timechunks2 = [["09:00", "10:00", "11:00"], ["09:00", "10:00", "11:00"], ["09:00", "10:00"]]
for (let i=0; i< timechunks.length; i++) {
differences.push(_.difference(timechunks[0], timechunks[i]))
}
Would need to extract 12:00 since it doesn't appear in others. Closest I got was with underscore _difference but alas it's not doing what I expected.
For timechunks1 I'm looking to return "12:00" For timechunks2 I'm looking for a way to return "11:00"
Added another example
[
["09:00", "10:00", "11:00" ,"13:00"],
["09:00", "10:00", "11:00", "13:00"],
["09:00", "10:00", "11:00", "12:00"]
]
for which it would return ["13:00", "12:00"]
Upvotes: 1
Views: 433
Reputation: 4366
In set-theoretic terms, what you are looking for is the symmetric difference. You can find this set by taking the union and subtracting the intersection:
function symmetricDifference(...sets) {
return _.difference(_.union(...sets), _.intersection(...sets));
}
Upvotes: 2
Reputation: 50787
You can build this on implementations of intersection
, difference
, and uniq
. Here's how I might do it with Ramda's versions:
const notCommon = (xs, common = xs .reduce (intersection)) =>
uniq (xs .flatMap (x => difference (x, common)))
const timechunks1 = [["09:00", "10:00", "11:00"], ["09:00", "10:00", "11:00"], ["09:00", "10:00", "11:00", "12:00"]]
const timechunks2 = [["09:00", "10:00", "11:00"], ["09:00", "10:00", "11:00"], ["09:00", "10:00"]]
const timechunks3 = [["09:00", "10:00", "11:00" ,"13:00"], ["09:00", "10:00", "11:00", "13:00"], ["09:00", "10:00", "11:00", "12:00"]]
console .log (notCommon (timechunks1))
console .log (notCommon (timechunks2))
console .log (notCommon (timechunks3))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.js"></script>
<script> const {intersection, uniq, difference} = R </script>
We find the elements in common to all the sets by using intersection
Here we reduce
over Ramda's binary version. Other versions might let you do something like common = intersection (xs)
or common = intersection (...xs)
, depending on their exact API. Then we flatMap
a difference
function over the timechunks, returning the values not found in common
. And finally we take only the uniq elements of that list.
Upvotes: 1
Reputation: 14891
You could achieve that by following these steps:
_.intersection(...timechunks)
_.difference(timechunk, commons)
Below snippet could help you
const timechunks1 = [
["09:00", "10:00", "11:00"],
["09:00", "10:00", "11:00"],
["09:00", "10:00", "11:00", "12:00"],
]
const timechunks2 = [
["09:00", "10:00", "11:00"],
["09:00", "10:00", "11:00"],
["09:00", "10:00"],
]
const timechunks3 = [
["09:00", "10:00", "11:00", "13:00"],
["09:00", "10:00", "11:00", "13:00"],
["09:00", "10:00", "11:00", "12:00"],
]
const getDifferences = (timechunks) =>
_.chain(timechunks)
.map((timechunk) => _.difference(timechunk, _.intersection(...timechunks)))
.flatten()
.uniq()
.value()
console.log(getDifferences(timechunks1))
console.log(getDifferences(timechunks2))
console.log(getDifferences(timechunks3))
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>
Upvotes: 0
Reputation: 1697
function findUniqueTimeSlots(timechunks) {
const hm = {};
timechunks.flat(1).forEach(el => {
if (hm.hasOwnProperty(el)) {
hm[el] += 1;
} else {
hm[el] = 1;
}
});
return Object.keys(hm).filter(key => hm[key] === 1);
}
Upvotes: 0
Reputation: 1285
Here is an immutable way of doing it
function findTimeSlot(timechunks){
const slots = _.map(_.zip(...timechunks), _.compact);
const maxChunk = _.max(_.map(slots, slot => slot.length));
return _.unique(_.find(slots, (slot) => slot.length < maxChunk));
}
returns
["11:00"]
forfindTimeSlot(timechunks2)
And
["12:00"]
forfindTimeSlot(timechunks1)
Let know if it works.
Upvotes: 0