JSFiddle - React, Tailwind, and code Playground
by Stepan Parunashvili
JavaScript
function parseCSV(csvStr) {
return csvStr
.trim()
.split("\n")
.reduce((res, rowStr) => {
const [name, cityStr] = rowStr.split(":");
return res.set(name.trim(), new Set(cityStr.split(",")));
}, new Map());
}
function intersect(setA, setB) {
return new Set([...setA].filter(x => setB.has(x)));
}
function difference(setA, setB) {
return new Set([...setA].filter(x => !setB.has(x)));
}
function nameToInfo(myName, nameToCities) {
const myCities = nameToCities.get(myName);
const nameToInfo = [...nameToCities.entries()]
.filter(([name, cities]) => name !== myName)
.map(([name, cities]) => [name, cities, intersect(myCities, cities)]);
const myCount = myCities.size;
return nameToInfo
.filter(([name, cities, intersection]) => {
return intersection.size / myCount >= 0.5;
})
.sort(
(
[_nameA, _citiesA, intersectionA],
[_nameB, _citiesB, intersectionB]
) => {
return intersectionB.size - intersectionA.size;
}
);
}
function bestTravelBuddies(myName, nameToCities) {
return nameToInfo(myName, nameToCities).map(
([name, _cities, _intersection]) => name
);
}
function bestRecommendations(myName, nameToCities) {
return nameToInfo(myName, nameToCities)
.map(([name, cities, intersection]) => {
return difference(cities, intersection);
})
.reduce((res, xs) => {
xs.forEach(x => res.add(x));
return res;
}, new Set());
}
const NAME = "Stepan";
const strOne = `
Jack:BJ,SEA,
Joe:LA,MTA,
`;
// const firstOne = parseCSV(strOne);
// console.log("we parsed correctly", firstOne);
const strWithOneMatch = `
Jack:BJ,SEA,SF
Jane:BJ,SEA,MTA,SF,LA
Joe:LA,MTA,SF,NYC,SF
Stepan:BJ,SEA,MTA
`;
const shouldBeOneMatch = parseCSV(strWithOneMatch);
console.log(
"expecting [Jane, Jack]",
bestTravelBuddies(NAME, shouldBeOneMatch)
);
console.log(
"expecting [[SF, LA], [SF]]",
bestRecommendations(NAME, shouldBeOneMatch)
);