Here is the input I am working with:
interface Option{
name:string
travelMode:string
}
const options:Option[] = [
{
name:"john",
travelMode:"bus"
},
{
name:"john",
travelMode:"car"
},
{
name:"kevin",
travelMode:"bus"
},
{
name:"kevin",
travelMode:"car"
},
]
I am trying to find all possible combinations of length 2 within this collection. To achieve this, I have implemented the following function :
const getCombinations=(options:Option[],startIndex:number,combination:Option[],combinationSize:number)=>{
if (combination.filter(e => e!==undefined).length === combinationSize)
{
console.log(combination)
}
else if (startIndex<options.length){
combination[startIndex]=undefined
getCombinations(options,startIndex+1,combination,combinationSize)
combination[startIndex]=options[startIndex]
getCombinations(options,startIndex+1,combination,combinationSize)
}
}
getCombinations(options,0,[],2)
The output looks promising, but I have a concern and an issue to resolve:
My concern: Why do all the printed combinations have a length of 4? According to my logic, the recursion should stop once we have 2 defined elements. I am puzzled as to why the last combination in the output has 4 elements (the first 2 are defined and the remaining 2 are undefined) => It seems like the program continues to iterate even after having 2 elements in its combination, which is not what I intended.
Issue to resolve: I want to exclude combinations where the names are the same. I only want combinations with 2 distinct names (i.e., john and kevin, but not john and john or kevin and kevin). Initially, I thought about calculating all combinations and then removing the duplicates at the end, but that doesn't seem efficient, especially when dealing with larger datasets. So, I attempted an alternative solution (stop the program if an individual has already been visited):
const getCombinations=(options:Option[],startIndex:number,combination:Option[],combinationSize:number)=>{
if (combination.filter(e => e!==undefined).length === combinationSize)
{
console.log(combination)
}
else if (startIndex<options.length){
combination[startIndex]=undefined
getCombinations(options,startIndex+1,combination,combinationSize)
let individualAlreadyVisited = false
if (startIndex>0)
{
for (let i =0;i<startIndex;i++)
{
if (combination[i] && combination[i].name===options[startIndex].name)
{
individualAlreadyVisited=true
break
}
}
}
if (!individualAlreadyVisited)
{
combination[startIndex]=options[startIndex]
getCombinations(options,startIndex+1,combination,combinationSize)
}
}
}
getCombinations(options,0,[],2)
Unfortunately, this approach is not yielding the expected results. The output still contains combinations with repeated names and some combinations seem to be missing. For example, the combination { name: 'john', travelMode: 'bus' }, { name: 'kevin', travelMode: 'car' } is not being displayed.
If anyone could provide assistance on this matter, I would greatly appreciate it. I have invested several hours into understanding and achieving the desired outcome without success so far.