Home » Get names in a sorted

Get names in a sorted

Get names in a sorted order under subject columns. Repeat them over Mon to Fri. Unused ones should carry over to Backup days.

📌 Challenge Details and Links
ExcelBI Power Query Challenge Number: 245
Challenge Difficulty: ⭐️⭐️⭐️⭐️
📥Download Sample File
📥Link to the solutions on LinkedIn

Solving the challenge of Get names in a sorted with Power Query

Power Query solution 1 for Get names in a sorted, proposed by Zoran Milokanović:
let
  Source = Excel.CurrentWorkbook(){[Name = "Input"]}[Content], 
  _ = Table.Group(
    Table.FromRows(
      List.Sort(
        List.TransformMany(Table.ToRows(Source), each Text.Split(_{1}, ", "), (i, _) => {i{0}, _}), 
        {each _{1}, each _{0}}
      ), 
      {"N", "S"}
    ), 
    "S", 
    {"A", each List.Repeat([N], Number.RoundUp(5 / List.Count([N])))}
  ), 
  S = Table.FromColumns(
    {
      List.Transform(
        {0 .. List.Max(List.Transform([A], List.Count)) - 1}, 
        each {"Mon", "Tue", "Wed", "Thu", "Fri"}{_}? ?? "Backup" & Text.From(_ - 4)
      )
    }
      & [A], 
    {"Days"} & [S]
  )
in
  S
Power Query solution 2 for Get names in a sorted, proposed by Alejandro Simón 🇵🇦 🇪🇸:
let
  Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  Split = Table.TransformColumns(Source, {{"Subjects", each Text.Split(_, ", ")}}), 
  Exp = Table.ExpandListColumn(Split, "Subjects"), 
  Group = Table.Sort(
    Table.Group(
      Exp, 
      {"Subjects"}, 
      {
        {
          "A", 
          each 
            let
              a = List.Sort([Names]), 
              b = List.Count(a), 
              c = List.Repeat(a, Number.RoundUp(5 / b))
            in
              c
        }
      }
    ), 
    "Subjects"
  ), 
  Max = List.Max(List.Transform(Group[A], List.Count)), 
  Days = {"Mon", "Tue", "Wed", "Thu", "Fri"}
    & List.Transform({1 .. Max - 5}, each "Backup" & Text.From(_)), 
  Sol = Table.FromColumns({Days} & Group[A], {"Days"} & Group[Subjects])
in
  Sol
Power Query solution 3 for Get names in a sorted, proposed by Luan Rodrigues:
let
  days = {"Mon", "Tue", "Wed", "Thu", "Fri"}, 
  sort = Table.Sort(Tabela1, {"Names"}), 
  spt = Table.TransformColumns(sort, {"Subjects", each Text.Split(_, ", ")}), 
  exp = Table.ExpandListColumn(spt, "Subjects"), 
  grp = Table.Group(
    exp, 
    {"Subjects"}, 
    {
      {
        "tab", 
        each [
          a = Table.Repeat(_, Number.RoundUp(List.Count(days) / List.Count(_[Names]))), 
          b = days
            & List.RemoveLastN(
              List.Transform({1 .. List.Count(a[Names])}, each "Backup" & Text.From(_)), 
              List.Count(days)
            ), 
          c = Table.FromColumns({b} & Table.ToColumns(a))
        ]
      }
    }
  ), 
  cls = Table.Sort(grp, {"Subjects"}), 
  cmb = Table.Combine(List.Transform(cls[tab], (x) => x[c])), 
  pvt = Table.Pivot(cmb, List.Distinct(cmb[Column3]), "Column3", "Column2"), 
  srt = Table.Sort(pvt, {each List.PositionOf(List.Distinct(cmb[Column1]), [Column1])}), 
  ren = Table.RenameColumns(srt, {{"Column1", "Days"}})
in
  ren
Power Query solution 4 for Get names in a sorted, proposed by Eric Laforce:
let
  Source = Excel.CurrentWorkbook(){[Name = "tData245"]}[Content], 
  Transform = Table.FromRows(
    List.Accumulate(
      Table.ToRows(Source), 
      {}, 
      (s, c) => s & List.Transform(Text.Split(c{1}, ", "), each {c{0}, _})
    ), 
    {"Name", "Subject"}
  ), 
  Group = Table.Group(
    Transform, 
    "Subject", 
    {"G", each List.Repeat(List.Sort(_[Name]), Number.RoundUp(5 / List.Count(_[Name])))}
  ), 
  Sort = Table.Sort(Group, "Subject"), 
  NbBackup = List.Max(List.Transform(Sort[G], List.Count)) - 5, 
  Backups = List.Transform({1 .. NbBackup}, each "Backup" & Text.From(_)), 
  ToTable = Table.FromColumns(
    {{"Mond", "Tue", "Wed", "Thu", "Fri"} & Backups} & Sort[G], 
    {"Days"} & Sort[Subject]
  )
in
  ToTable
Power Query solution 5 for Get names in a sorted, proposed by Seokho MOON:
let
  Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  ToList = Table.TransformColumns(Source, {{"Subjects", each Text.Split(_, ", ")}}), 
  Expand = Table.ExpandListColumn(ToList, "Subjects"), 
  Group = Table.Sort(
    Table.Group(Expand, {"Subjects"}, {"tbl", each Table.Sort(_, "Names")[Names]}), 
    "Subjects"
  ), 
  Names = List.Transform(Group[tbl], each List.Repeat(_, Number.RoundUp(5 / List.Count(_)))), 
  Backups = List.Max(List.Transform(Names, each List.Count(_))) - 5, 
  Days = {
    {"Mon", "Tue", "Wed", "Thu", "Fri"}
      & List.Transform({1 .. Backups}, each "Backup" & Text.From(_))
  }, 
  Cols = Days & Names, 
  ColNames = {"Days"} & Group[Subjects], 
  Res = Table.FromColumns(Cols, ColNames)
in
  Res
Power Query solution 6 for Get names in a sorted, proposed by 🇮🇷 Navid Esmaeilzadeh اسماعیل زاده:
let
  S = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  DL = {"Mon", "Tue", "Wed", "Thu", "Fri"}, 
  A = Table.AddColumn(S, "SL", each Text.Split([Subjects], ", ")), 
  B = Table.SelectColumns(A, {"Names", "SL"}), 
  C = Table.ExpandListColumn(B, "SL"), 
  D = Table.Group(C, {"SL"}, {{"C", each Table.RowCount(_)}, {"T", each _}}), 
  E = Table.AddColumn(
    D, 
    "Name(R)", 
    each List.Repeat([T][Names], Number.RoundUp(List.Count(DL) / [C]))
  ), 
  F = Table.AddColumn(E, "LC", each List.Count([#"Name(R)"])), 
  G = Table.Sort(F, {{"SL", Order.Ascending}}), 
  DLN = DL & List.Transform({1 .. List.Max(G[LC]) - List.Count(DL)}, each "Backup" & Text.From(_)), 
  H = Table.FromColumns(G[#"Name(R)"], G[SL]), 
  I = Table.AddColumn(H, "D", each DLN), 
  K = Table.AddIndexColumn(I, "I", 0, 1), 
  L = Table.AddColumn(K, "Days", each [D]{[I]}), 
  M = Table.ReorderColumns(L, {"Days", "Arts", "English", "Maths", "D", "I"}), 
  N = Table.SelectColumns(M, {"Days", "Arts", "English", "Maths"})
in
  N

Solving the challenge of Get names in a sorted with Excel

Excel solution 1 for Get names in a sorted, proposed by Bo Rydobon 🇹🇭:
=LET(
    s,
    TEXTSPLIT(
        TEXTJOIN(
            0,
            0,
            B2:B6
        ),
        ", ",
        0
    ),
    
    g,
    TRANSPOSE(
        TEXTSPLIT(
            CONCAT(
                GROUPBY(
                    TOCOL(
                        s,
                        3
                    )&" ",
                    TOCOL(
                        IF(
                            s>0,
                            A2:A6
                        ),
                        3
                    ),
                    LAMBDA(
                        x,
                        REPT(
                            CONCAT(
                                SORT(
                                    x
                                )&" "
                            ),
                            ROUNDUP(
                                5/ROWS(
                                    x
                                ),
                                
                            )
                        )&0
                    ),
                    ,
                    0
                )
            ),
            " ",
            0,
            1,
            ,
            ""
        )
    ),
    n,
    SEQUENCE(
        ROWS(
            g
        )
    ),
    
    HSTACK(
        IFS(
            n=1,
            "Day",
            n>6,
            "Backup"&n-6,
            1,
            TEXT(
                n,
                "ddd"
            )
        ),
        g
    )
)
Excel solution 2 for Get names in a sorted, proposed by Julian Poeltl:
=LET(N,
    A2:A6,
    S,
    B2:B6,
    H,
    TOROW(
        SORT(
            UNIQUE(
                TEXTSPLIT(
                    TEXTJOIN(
                        ", ",
                        ,
                        S
                    ),
                    ,
                    ", "
                )
            )
        )
    ),
    NBS,
    MAP(
        H,
        LAMBDA(
            A,
            TEXTJOIN(
                ",",
                ,
                SORT(
                    FILTER(
                        N,
                        ISNUMBER(
                            SEARCH(
                                A,
                                S
                            )
                        )
                    )
                )
            )
        )
    ),
    T,
    IFNA(DROP(REDUCE(0,
    MAP(NBS,
    LAMBDA(A,
    REPT(A&",",
    ROUNDUP(6/(LEN(
        A
    )-LEN(
        SUBSTITUTE(
            A,
            ",",
            ""
        )
    )+1),
    0)))),
    LAMBDA(
        A,
        B,
        HSTACK(
            A,
            TEXTSPLIT(
                B,
                ,
                ","
            )
        )
    )),
    -1,
    1),
    ""),
    HSTACK(
        VSTACK(
            "Days",
            TEXT(
                SEQUENCE(
                    5,
                    ,
                    2
                ),
                "TTT"
            ),
            "Backup"&SEQUENCE(
                3
            )
        ),
        VSTACK(
            H,
            T
        )
    ))
Excel solution 3 for Get names in a sorted, proposed by Hussein SATOUR:
=LET(
    W,
    ARRAYTOTEXT,
    P,
    TEXTSPLIT,
    S,
    SEQUENCE,
    V,
    VSTACK,
    n,
    A2:A6,
    u,
    B2:B6,
    b,
    CONCAT(
        BYROW(
            SORT(
                UNIQUE(
                    P(
                        W(
                            u
                        ),
                        ,
                        ", "
                    )
                )
            ),
            LAMBDA(
                z,
                z&", "&LET(
                    a,
                    SORT(
                        FILTER(
                            n,
                            IFERROR(
                                FIND(
                                    z,
                                    u
                                ),
                                0
                            )
                        )
                    ),
                    W(
                        REDUCE(
                            a,
                            S(
                                ROUNDDOWN(
                                    5/COUNTA(
                                        a
                                    ),
                                    0
                                )
                            ),
                            LAMBDA(
                                x,
                                y,
                                V(
                                    x,
                                    a
                                )
                            )
                        )
                    )&"/"
                )
            )
        )
    ),
    c,
    TRANSPOSE(
        P(
            b,
            ", ",
            "/",
            1,
            ,
            ""
        )
    ),
    HSTACK(
        V(
            "Days",
            TEXT(
                S(
                    5,
                    ,
                    2
                ),
                "ddd"
            ),
            "Backup"&S(
                ROWS(
                    c
                )-6
            )
        ),
        c
    )
)
Excel solution 4 for Get names in a sorted, proposed by Oscar Mendez Roca Farell:
=LET(
    t,
     TEXTSPLIT(
         CONCAT(
             B2:B6&", "
         ),
         ,
         ", ",
         1
     ),
     s,
     SEQUENCE(
         1+MAX(
             6,
             2*MOD(
                 DROP(
                     GROUPBY(
                         t,
                         t,
                         ROWS,
                         ,
                         0
                     ),
                     ,
                     1
                 ),
                 5
             )
         )
     )-1,
     REDUCE(
         IFS(
             s>5,
             "Backup"&MOD(
                 s,
                 5
             ),
             s=0,
             "Days",
             1,
             TEXT(
                 s+1,
                 "b1ddd"
             )
         ),
          SORT(
              UNIQUE(
                  t
              )
          ),
         LAMBDA(
             i,
             x,
             LET(
                 m,
                 TOCOL(
                     IFS(
                         FIND(
                             x,
                             B2:B6
                         ),
                         A2:A6
                     ),
                     2
                 ),
                 r,
                  ROWS(
                      m
                  ),
                 IFNA(
                     HSTACK(
                         i,
                         VSTACK(
                             x,
                             TOCOL(
                                 REPT(
                                     SORT(
                      m
                  ),
                                     SEQUENCE(
                                         ,
                                          IF(
                                              MOD(
                                                  r-1,
                                                  4
                                              ),
                                              1+5/r,
                                              1
                                          )
                                     )^0
                                 ),
                                 ,
                                 1
                             )
                         )
                     ),
                     ""
                 )
             )
         )
     )
)
Excel solution 5 for Get names in a sorted, proposed by Sunny Baggu:
=LET(
    
     _s,
     TOROW(
         SORT(
             UNIQUE(
                 TEXTSPLIT(
                     ARRAYTOTEXT(
                         B2:B8
                     ),
                      ,
                      {",",
                      ", "},
                      1
                 )
             )
         )
     ),
    
     _a,
     DROP(
         
          REDUCE(
              "",
               _s,
               LAMBDA(
                   a,
                    v,
                    HSTACK(
                        a,
                         SORT(
                             TOCOL(
                                 IF(
                                     SEARCH(
                                         v,
                                          B2:B8
                                     ),
                                      A2:A8,
                                      x
                                 ),
                                  3
                             )
                         )
                    )
               )
          ),
         
          ,
         
          1
          
     ),
    
     _r,
     BYCOL(
         SEARCH(
             _s,
              B2:B8
         ),
          LAMBDA(
              a,
               ROWS(
                   TOCOL(
                       a,
                        3
                   )
               )
          )
     ),
    
     _rm,
     MAX(
         _r
     ),
    
     _wd,
     5,
    
     _rt,
     IF(
         _rm < 7,
          2 * _rm,
          5
     ),
    
     _rp,
     ROUNDUP(
         _wd / _r,
          0
     ),
    
     _b,
     SEQUENCE(
         _rt
     ) - _wd,
    
     _d,
     IF(
         _b > 0,
          "Backup" & _b,
          {"Mon"; "Tue"; "Wed"; "Thu"; "Fri"}
     ),
    
     _e,
     IFNA(
         
          DROP(
              
               REDUCE(
                   
                    "",
                   
                    SEQUENCE(
                        COLUMNS(
                            _a
                        )
                    ),
                   
                    LAMBDA(
                        x,
                         y,
                        
                         HSTACK(
                             
                              x,
                             
                              TOCOL(
                                  IF(
                                      SEQUENCE(
                                          ,
                                           INDEX(
                                               &_rp,
                                                1,
                                                y
                                           )
                                      ),
                                       TOCOL(
                                           INDEX(
                                               _a,
                                                ,
                                                y
                                           ),
                                            3
                                       )
                                  ),
                                   ,
                                   1
                              )
                              
                         )
                         
                    )
                    
               ),
              
               ,
              
               1
               
          ),
         
          ""
          
     ),
    
     _dr,
     TAKE(
         _d,
          ROWS(
              _e
          )
     ),
    
     _fr,
     VSTACK(
         HSTACK(
             "Days",
              _s
         ),
          HSTACK(
              _dr,
               _e
          )
     ),
    
     _fr
    
)
Excel solution 6 for Get names in a sorted, proposed by Md. Zohurul Islam:
=LET(
    
    nam,
    A2:A6,
    
    sub,
    B2:B6,
    
    dys,
    TEXT(
        SEQUENCE(
            5,
            ,
            2
        ),
        "ddd"
    ),
    
    a,
    MAP(
        nam,
        sub,
        LAMBDA(
            x,
            y,
            REPT(
                x&",",
                COUNTA(
                    TEXTSPLIT(
                        y,
                        ", "
                    )
                )
            )
        )
    ),
    
    b,
    DROP(
        TEXTSPLIT(
            CONCAT(
                a
            ),
            ,
            ","
        ),
        -1
    ),
    
    p,
    DROP(
        REDUCE(
            "",
            sub,
            LAMBDA(
                x,
                y,
                VSTACK(
                    x,
                    TEXTSPLIT(
                        y,
                        ,
                        ", "
                    )
                )
            )
        ),
        1
    ),
    
    u,
    TOROW(
        SORT(
            UNIQUE(
                p
            )
        )
    ),
    
    v,
    DROP(
        REDUCE(
            "",
            u,
            LAMBDA(
                x,
                y,
                LET(
                    f,
                    SORT(
                        FILTER(
                            b,
                            p=y
                        )
                    ),
                    g,
                    COUNTA(
                        f
                    ),
                    h,
                    ROUNDUP(
                        5/g,
                        0
                    ),
                    
                    j,
                    IFS(
                        h=5,
                        VSTACK(
                            f,
                            f,
                            f,
                            f,
                            f
                        ),
                        h=4,
                        VSTACK(
                            f,
                            f,
                            f,
                            f
                        ),
                        h=3,
                        VSTACK(
                            f,
                            f,
                            f
                        ),
                        h=2,
                        VSTACK(
                            f,
                            f
                        ),
                        h=1,
                        f
                    ),
                    k,
                    HSTACK(
                        x,
                        j
                    ),
                    k
                )
            )
        ),
        ,
        1
    ),
    
    w,
    IFNA(
        VSTACK(
            u,
            v
        ),
        ""
    ),
    
    q,
    ROWS(
        v
    )-5,
    
    r,
    "Backup" &SEQUENCE(
        q
    ),
    
    s,
    VSTACK(
        "Days",
        dys,
        r
    ),
    
    z,
    HSTACK(
        s,
        w
    ),
    
    z
)
Excel solution 7 for Get names in a sorted, proposed by Md Ismail Hosen:
=LAMBDA(
    NamesVsSubjectMap,
     LET(
         _Days,
          VSTACK(
              "Mon",
               "Tue",
               "Wed",
               "Thu",
               "Fri"
          ),
          _DaysCount,
          ROWS(
              _Days
          ),
          _SubjectVsNameMap,
          DROP(
              REDUCE(
                  "",
                   SEQUENCE(
                       ROWS(
                           NamesVsSubjectMap
                       )
                   ),
                   LAMBDA(
                       a,
                       c,
                        LET(
                            Subjects,
                             TEXTSPLIT(
                                 INDEX(
                                     NamesVsSubjectMap,
                                      c,
                                      2
                                 ),
                                  " ",
                                  ", "
                             ),
                             Result,
                             VSTACK(
                                 a,
                                  EXPAND(
                                      Subjects,
                                       ,
                                       2,
                                       INDEX(
                                           NamesVsSubjectMap,
                                            c,
                                            1
                                       )
                                  )
                             ),
                             Result
                        )
                   )
              ),
               1
          ),
          _SubjectExpanded,
          TAKE(
              _SubjectVsNameMap,
               ,
               1
          ),
          _StudentNameExpanded,
          TAKE(
              _SubjectVsNameMap,
               ,
               -1
          ),
          _SubjectByStudentCount,
          GROUPBY(
              _SubjectExpanded,
               _StudentNameExpanded,
               ROWS,
               0,
               0
          ),
          _RelevantSubjectStudentNames,
          BYROW(
              _SubjectByStudentCount,
               LAMBDA(
                   row,
                    REPT(
                        CONCAT(
                            SORT(
                                FILTER(
                                    _StudentNameExpanded,
                                     _SubjectExpanded = INDEX(
                                         row,
                                          1,
                                          1
                                     )
                                )
                            ) & ", "
                        ),
                         ROUNDUP(
                             _DaysCount / INDEX(
                                 row,
                                  1,
                                  2
                             ),
                              0
                         )
                    )
               )
          ),
          _StudentsNameExpanded,
          IFNA(
              DROP(
                  REDUCE(
                      "",
                       _RelevantSubjectStudentNames,
                       LAMBDA(
                           a,
                           c,
                            HSTACK(
                                a,
                                 TEXTSPLIT(
                                     c,
                                      " ",
                                      ", ",
                                      TRUE
                                 )
                            )
                       )
                  ),
                   ,
                   1
              ),
               ""
          ),
          _Headers,
          VSTACK(
              _Days,
               "Backup" & SEQUENCE(
                   ROWS(
                       _StudentsNameExpanded
                   ) - _DaysCount
               )
          ),
          _Result,
          VSTACK(
              HSTACK(
                  "Days",
                   TRANSPOSE(
                       TAKE(
                           _SubjectByStudentCount,
                            ,
                            1
                       )
                   )
              ),
               HSTACK(
                   _Headers,
                    _StudentsNameExpanded
               )
          ),
          _Result
     )
)(A2:B6)
Excel solution 8 for Get names in a sorted, proposed by Gabriel Pugliese:
=LET(
    d,
    A2:B6,
    
    sn,
    DROP(
        REDUCE(
            "",
            SEQUENCE(
                ROWS(
                    d
                )
            ),
            LAMBDA(
                a,
                v,
                VSTACK(
                    a,
                    REGEXEXTRACT(
                        INDEX(
                            TAKE(
                                d,
                                ,
                                -1
                            ),
                            v,
                            
                        ),
                        "w+",
                        1
                    )&"|"&INDEX(
                        TAKE(
                            d,
                            ,
                            1
                        ),
                        v,
                        
                    )
                )
            )
        ),
        1
    ),
    
    us,
    SORT(
        UNIQUE(
            TOCOL(
                DROP(
                    REDUCE(
                        "",
                        SEQUENCE(
                ROWS(
                    d
                )
            ),
                        LAMBDA(
                            a,
                            v,
                            VSTACK(
                                a,
                                REGEXEXTRACT(
                                    INDEX(
                            TAKE(
                                d,
                                ,
                                -1
                            ),
                            v,
                            
                        ),
                                    "w+",
                                    1
                                )
                            )
                        )
                    ),
                    1
                ),
                3
            )
        )
    ),
    
    nn,
    DROP(
        REDUCE(
            "",
            us,
            LAMBDA(
                a,
                v,
                HSTACK(
                    a,
                    SORT(
                        TOCOL(
                            IFS(
                                REGEXTEST(
                                    sn,
                                    v
                                ),
                                TEXTAFTER(
                                    sn,
                                    "|"
                                )
                            ),
                            3
                        )
                    )
                )
            )
        ),
        ,
        1
    ),
    
    numn,
    BYCOL(
        nn,
        LAMBDA(
            c,
            COUNTA(
                TOCOL(
                    c,
                    3
                )
            )
        )
    ),
    
    rep,
    ROUNDUP(
        5/numn,
        0
    ),
    
    gr,
    REDUCE(
        "",
        SEQUENCE(
            COUNT(
                numn
            )
        ),
        LAMBDA(
            a,
            i,
            HSTACK(
                a,
                DROP(
                    REDUCE(
                        "",
                        SEQUENCE(
                            SUM(
                                INDEX(
                                    rep,
                                    ,
                                    i
                                )
                            )
                        ),
                        LAMBDA(
                            a,
                            v,
                            VSTACK(
                                a,
                                TOCOL(
                                    INDEX(
                                        nn,
                                        ,
                                        i
                                    ),
                                    3
                                )
                            )
                        )
                    ),
                    1
                )
            )
        )
    ),
    
    l,
    TOCOL(
        HSTACK(
            TEXT(
                SEQUENCE(
                    ,
                    5,
                    2
                ),
                "ddd"
            ),
            "backup"&SEQUENCE(
                ,
                ROWS(
                    gr
                )-5
            )
        )
    ),
    
    rst,
    IFNA(
        VSTACK(
            HSTACK(
                "Days",
                TOROW(
                    us
                )
            ),
            HSTACK(
                l,
                DROP(
                    gr,
                    ,
                    1
                )
            )
        ),
        ""
    ),
    rst
)

Solving the challenge of Get names in a sorted with Python

Python solution 1 for Get names in a sorted, proposed by Konrad Gryczan, PhD:
import pandas as pd
import numpy as np
path = "PQ_Challenge_245.xlsx"
input = pd.read_excel(path, usecols="A:B", nrows=6)
test = pd.read_excel(path, usecols="D:G", nrows=9).fillna('')
input = input.assign(Subjects=input['Subjects'].str.split(', ')).explode('Subjects')
r1 = input.groupby('Subjects')['Names'].apply(lambda x: sorted(x.tolist())).reset_index()
weekdays = ["Mon", "Tue", "Wed", "Thu", "Fri"]
weekday_n = len(weekdays)
subjects_list = r1.set_index('Subjects')['Names'].apply(lambda x: np.array(x)).to_dict()
longest_subject = max(map(len, subjects_list.values()))
first_col = [""] * (longest_subject * -(-weekday_n // longest_subject))
subjects = {k: np.tile(v, -(-weekday_n // len(v))) for k, v in subjects_list.items()}
df = pd.DataFrame({
 'Days': weekdays + [f"Backup{i}" for i in range(1, len(first_col) - weekday_n + 1)],
 **{subject: np.concatenate([names, [''] * (len(first_col) - len(names))]) for subject, names in subjects.items()}
})
print(df.equals(test)) # True
                    
                  

Solving the challenge of Get names in a sorted with Python in Excel

Python in Excel solution 1 for Get names in a sorted, proposed by Alejandro Campos:
data_input = xl("A1:B6", headers=True).assign(Subjects=lambda df: df['Subjects'].str.split(', ')).explode('Subjects')
subjects_dict = data_input.groupby('Subjects')['Names'].apply(lambda x: np.array(sorted(x))).to_dict()
max_len = max(map(len, subjects_dict.values()))
weekdays = ["Mon", "Tue", "Wed", "Thu", "Fri"]
first_col_len = max_len * -(-len(weekdays) // max_len)
subjects_repeated = {subj: np.tile(names, -(-len(weekdays) // len(names))) for subj, names in subjects_dict.items()}
first_col = weekdays + [f"Backup{i}" for i in range(1, first_col_len - len(weekdays) + 1)]
schedule_df = pd.DataFrame({
 'Days': first_col,
 **{subj: np.pad(names, (0, len(first_col) - len(names)), constant_values='') for subj, names in subjects_repeated.items()}
})
schedule_df
                    
                  

Solving the challenge of Get names in a sorted with R

R solution 1 for Get names in a sorted, proposed by Konrad Gryczan, PhD:
library(tidyverse)
library(readxl)
path = "Power Query/PQ_Challenge_245.xlsx"
input = read_excel(path, range = "A1:B6")
test = read_excel(path, range = "D1:G9")
r1 = input %>%
 separate_rows(Subjects, sep = ", ") %>%
 group_by(Subjects) %>%
 summarise(Names = list(sort(Names)), .groups = 'drop')
weekdays = c("Mon", "Tue", "Wed", "Thu", "Fri")
weekday_n = length(weekdays)
subjects_list = r1 %>%
 summarise(Names = list(unlist(Names)), .by = Subjects) %>%
 deframe()
longest_subject = max(map_int(r1$Names, length))
first_col = rep("", longest_subject * ceiling(weekday_n / longest_subject))
subjects = map(subjects_list, ~ rep(.x, ceiling(weekday_n / length(.x))))
df = tibble(
 Days = c(weekdays, map_chr(seq_along(first_col) - weekday_n, ~paste0("Backup", .x))),
 Arts = c(subjects[["Arts"]], rep(NA, length(first_col) - length(subjects[["Arts"]]))),
 English = c(subjects[["English"]], rep(NA, length(first_col) - length(subjects[["English"]]))),
 Maths = c(subjects[["Maths"]], rep(NA, length(first_col) - length(subjects[["Maths"]])))
)
all.equal(df, test, check.attributes = FALSE)
# TRUE
                    
                  

Leave a Reply