Forum Discussion

Patrick2788's avatar
Patrick2788
Silver Contributor
Feb 05, 2026

WrapRows2Dλ / WrapCols2Dλ: Fast, efficient 2D wrapping without flattening

 

Background

One of Excel's biggest weaknesses is in working with 2D arrays as objects that can be re-shaped.

WRAPROWS/WRAPCOLS do not accept 2D arrays (#VALUE!) and are strictly for shaping 1D arrays.  The usual workarounds involve flattening with TOROW/TOCOL then re-shaping with WRAPROWS/WRAPCOLS, REDUCE used an iterator to stack (do-able but slow), and even MAKEARRAY (do-able, but not instinctive and slow).

The Goal

Fast, efficient 2D wrapping without flattening.

The Approach

Pure deferred i/j indexing with modular math and sequencing.

The function and sample workbook is provided below. I welcome any and all feedback: suggestions for improvement, your approach to 2D shaping, etc.

// Fast, efficient 2D wrapping without flattening

//-----------------------------------------------------------------------------------
//---WrapCols2Dλ---
//-----------------------------------------------------------------------------------
//Author:   Patrick H.
//Date:     1/28/2026
//Version:  1.0
//
//Description:
//Wrap a 2D array into column blocks of a specified width while preserving row height.
//The wrapped blocks are stacked vertically in the output.
//Jagged or uneven final blocks are padded with NA() by default, unless a fill value
//is supplied via the optional pad_with parameter.
//
//-----------------------------------------------------------------------------------
//Parameter       Description
//array           - 2D array to be wrapped (1D arrays not supported)
//new_width       - Number of columns in each wrapped block
//
//Optional        Description
//pad_with        - Fill value used to pad incomplete blocks. If omitted, NA() is used.
//
//Lambda called: Echoλ


WrapCols2Dλ=
LAMBDA(
    array,
    new_width,
    [pad_with],

//Check inputs
LET(
    //Shape 
    h,          ROWS(array),
    w,          COLUMNS(array),
    blocks,     CEILING(w/new_width,1),

    //Optional
    pad_with,   IF(ISOMITTED(pad_with),NA(),pad_with),
    
    //Total rows when wrapped
    r,          blocks * h,

    //Scenarios
    Is1D?,      OR(h = 1,w = 1),
    IsScalar?,  AND(h = 1, w = 1),
    InvalidDim?,new_width >= w,
    SpillRisk?, r > 1048576,

    //Logic gate
    IF(IsScalar?,#VALUE!,
        IF(Is1D?,#VALUE!,
            IF(InvalidDim?,"#WIDTH!",
                IF(SpillRisk?,#NUM!,

//Proceed
LET(
    //Indices - deferred
    modulo, LAMBDA(MOD(SEQUENCE(r),h)),
    i,      LAMBDA(IF(modulo() = 0, h, modulo()) * SEQUENCE(,new_width,1,0)),
    j,      LAMBDA(Echoλ(SEQUENCE(r / h,,1,new_width),h) + SEQUENCE(,new_width,0,1)),

    //Wrapped array
    result, IFERROR(INDEX(array,i(),j()),pad_with),
    result
    )))))));





//-----------------------------------------------------------------------------------
//---WrapRows2Dλ---
//-----------------------------------------------------------------------------------
//Author:   Patrick H.
//Date:     1/28/2026
//Version:  1.0
//
//Description:
//Wrap a 2D array into row blocks of a specified height while preserving column width.
//The wrapped blocks are stacked horizontally in the output.
//Jagged or uneven final blocks are padded with NA() by default, unless a fill value
//is supplied via the optional pad_with parameter.
//
//-----------------------------------------------------------------------------------
//Parameter       Description
//array           - 2D array to be wrapped (1D arrays not supported)
//new_height      - Number of rows in each wrapped block
//
//Optional        Description
//pad_with        - Fill value used to pad incomplete blocks. If omitted, NA() is used.
//
//Lambda called: Echoλ


WrapRows2Dλ=
LAMBDA(
    array,
    new_height,
    [pad_with],
//Check inputs
LET(
    //Shape 
    h,          ROWS(array),
    w,          COLUMNS(array),
    blocks,     CEILING(h/new_height,1),

    //Optional
    pad_with,   IF(ISOMITTED(pad_with),NA(),pad_with),
    
    //Total columns when unwrapped
    c,          blocks * w,

    //Scenarios
    Is1D?,      OR(h = 1,w = 1),
    IsScalar?,  AND(h = 1, w = 1),
    InvalidDim?,new_height >= h,
    SpillRisk?, c > 16384,

    //Logic gate
    IF(IsScalar?,#VALUE!,
        IF(Is1D?,#VALUE!,
            IF(InvalidDim?,"#HEIGHT!",
                IF(SpillRisk?,#NUM!,

//Proceed
LET(
    //Indices - deferred
    i,      LAMBDA(TOROW(Echoλ(SEQUENCE(,blocks,1,new_height),w)) + SEQUENCE(new_height,,0,1)),
    modulo, LAMBDA(MOD(SEQUENCE(,w * blocks),w)),
    j,      LAMBDA(IF(modulo()=0,w,modulo()) * SEQUENCE(new_height,,1,0)),

    //Wrapped array
    result, IFERROR(INDEX(array,i(),j()),pad_with),
    result
    )))))));



//-----------------------------------------------------------------------------------
//Echoλ
//-----------------------------------------------------------------------------------
//Author:   Patrick H.
//Date:   	11/7/2025
//Version:	1.0

//Description:
//Repeat each element in a supplied 1D array by specifying the repeat counts.
//Arrays and scalars are supported.
//-----------------------------------------------------------------------------------
//vector    -   1D array or scalar to be echoed
//repeat    -   1D array of repeat counts (must be numeric and ≥1)

Echoλ =
LAMBDA(
    vector,
    repeat,

//Check inputs
IF(OR(ISTEXT(repeat),repeat<=0),#VALUE!,

LET(
    //Flatten inputs
    vector,  TOCOL(vector), repeat,  TOCOL(repeat),

    //Dimensions and row indexing
    V↕,      ROWS(vector),  R↕,ROWS(repeat),

    r,       IF(V↕<>R↕,EXPAND(repeat,V↕,,@TAKE(repeat,-1)),
                 repeat),

    i,       SEQUENCE(ROWS(r)),

    m,       MAX(r),

    idx,     LAMBDA(TOCOL(IF(SIGN(r-SEQUENCE(,m,0,))=1,i,NA()),2)),

    //Unwrap idx but defer delivery until function invocation
    deliver, LAMBDA(INDEX(vector,idx())),

    deliver
))());

 

Workbook attached and linked in case this forum gobbles it up!

Patrick2788/Excel-Lambda: Excel Lambda modules

 

Excel-Lambda/Wrap2D Demo.xlsx at main · Patrick2788/Excel-Lambda

Excel Lambda modules. Contribute to Patrick2788/Excel-Lambda development by creating an account on GitHub.

github.com
No RepliesBe the first to reply

Resources