Search code examples
arraysgoogle-sheetslambda

How to Generate an Array in Google Sheets by splitting columns and duplicating rows


I have recently discovered the advanced Array formulas on Google Sheets (lambda, makearray, map etc). Yeah, I know, I am late to the party, but am very eager to learn how to use and understand these functions and no better way than to dive in with an advanced problem to practically apply the skills / knowledge....

Question

Is it possible, using one arrayformula with lambdas and other array functions to dynamically generate an array by iteratively applying logic to duplicate and generate rows and cells given a basic input?

Input

Dimension 1 Dimension 2 Pages
Red Large 1,2,3-5
Blue Small 6,7,8-10

Desired Output

Dimension 1 Dimension 2 Page
Red Large 1
Red Large 2
Red Large 3
Red Large 4
Red Large 5
Blue Small 6
Blue Small 7
Blue Small 8
Blue Small 9
Blue Small 10

Logic

1. Pages Field

The "Pages" column of the Input Table needs to be split, based on the below logic:

  • The value of "Pages" is a list of page numbers (similar to the format used when printing specific pages of a PDF document)
  • First iteration: split by ","
  • Next iteration: Split by "-"
  • Final Iteration: Where there is a range of numbers, use Sequence formula to generate the sequential numbers (eg. 3-5 = 3,4,5)

2. Other Dimensions Field

  • All other dimensions (ie. Dimension 1 and Dimension 2) will need to be duplicated accross the array generated above for the page numbers

Interim Attempts

I have only managed to generate the page number sequence using the below formula (assuming Input Data is in cells A5:A6, but the formula below is only considering the "Pages" column...)

=tocol(lambda(z,map(CHOOSECOLS(z,1),CHOOSECOLS(z,2),lambda(x,y,sequence(1,y-x+1,x,1))))

(lambda(y,arrayformula(if(CHOOSECOLS(y,2)="",CHOOSECOLS(y,1),y)))

(LAMBDA(x,arrayformula(split(flatten(split(x,",")),"-")))(C5:C6))),1)

Any attempts to either include, append or merge in Dimension 1 or 2 in the above output fails and I would like to know how to dynamically include these columns into the output?


Solution

  • You may try:

    =let(Σ,arrayformula(split(tocol(A2:A&"🐠"&B2:B&"🐠"&map(C2:C,lambda(Ξ,if(Ξ="",,let(Δ,split(substitute(Ξ,"-","🐠"),","),
           torow(reduce(,Δ,lambda(a,c,{a,let(Γ,--regexextract(c,"\d+"),if(regexmatch(c&"","🐠"),sequence(1,(--regexextract(c,"🐠(\d+)")-Γ)+1,Γ,1),c))})),1)))))),"🐠")),
           filter(Σ,index(Σ,,3)<>""))
    

    enter image description here