0

I have a scenario where user is allowed to select few attributes attribute1, attribute2 and so on. These attribute1, attribute2 are themselves list and if there is any selection were made, they are stored in them. If no selection made, then the list will be empty list. How to properly generate the combinations even in case of one of them is empty? For example:

Case1: attribute1 = ["a", "b"], attribute2=["1", "2"] => result = ["a1", "a2", "b1", "b2"]

Case2: attribute1 = ["a", "b"], attribute2=[] => result = ["a", "b"] and so on.

Also these lists are driven by user multi-selection from the dropdowns. Based on user selection, there could be attribute3, attribute4 and so on.

I saw few similar post solving the combinations but they do not consider the empty list. Please let me know if you have any suggestions.

Senthil
  • 323
  • 4
  • 15
  • what happens when `attribute1 = []` and `attribute2 = ["a", "b"]` – badger Jul 19 '21 at 15:05
  • Yes, you are right, in case of attribute1 = ["a", "b"], attribute2=[], then the result must be ["a", "b"]. – Senthil Jul 19 '21 at 15:41
  • if `attribute1 = []` and `attribute2 = ["a", "b"]` then again the result is `["a", "b"]` – Senthil Jul 19 '21 at 15:43
  • Though in my case, all these attributes have different values and unique, like attribute1 can have a,b as values and attribute2 do not have them. – Senthil Jul 19 '21 at 15:51

2 Answers2

0

In this case, empty list(s) if any exists, those needs to be eliminated before generating the combinations. Those empty lists just creating confusion and disrupting generating the combinations. enter image description here

Senthil
  • 323
  • 4
  • 15
0
function combine(lists: string[][]): string[] {
  if(lists.length === 0) return []
  if(lists.length === 1) return lists[0]

  let result = lists.shift()! // `!` is `NonNullable` assert in typescript
  let list: string[] | undefined
  while(list = lists.shift()) {
    if(!list.length) continue // skip empty list

    if(!result.length) { // if result is empty list
      result = [...list]
    } else {
      let combination: string[] = []
      for(let a of result) {  // you can use `flatMap` to instend of this double for of
          for (let b of list) {
              combination.push(`${a}${b}`)
          }
      }
      result = combination
    }
  }

  return result
}

combine([]) // => []
combine([[]]) // => []
combine([[], ["a", "b"]]) // => ["a", "b"] 
combine([["a", "b"], []]) // => ["a", "b"] 
combine([["a", "b"], ["1", "2"]]) // => ["a1", "a2", "b1", "b2"]
combine([["a", "b", "c"], [], ["1", "2"]]) // => ["a1", "a2", "b1", "b2", "c1", "c2"] 

You can test this on TS Playground.

hfutsora
  • 91
  • 4