Use of grouping in BICMD

I tried to implement bubble sort in BICMD by phoenetic string comparison turned out not to be supported 
But for my use case a method to group a 2D array of string by first key would do fine

/*  ----------------------------------------------------------------
    Peter Lykkegaard, 25 Oct 2025
    -----------------------------
    Name: groupByArray
    Description
        This code processes a 2D array "pvData$[][]" by grouping rows based on the value in the first column.
        It avoids reprocessing rows by marking them as "found" in "lvProcessedRows$[]".
        The grouped rows are stored in "lvGroupedData$[][]", preserving all column data.
        The algorithm uses nested loops to compare and group rows with matching keys.
    Parameters
        pvData$[][]	   - 2D array which should be grouped
    Output
        $[][]                     - 2D array grouped by keyword
    -------------------------------------------------------------- */

local 
    lvTotalRows%,         // Total number of rows in pvData$
    lvColumnIndex%,       // Index for iterating through columns
    lvNewRowIndex%,       // Index for inserting into lvGroupedData$
	lvKeyIndex%,          // Index for keyword for grouping	  
    lvTotalColumns%,      // Total number of columns in pvData$
    lvCurrentRow%,        // Current row being processed
    lvCurrentKey$,        // Key value from the first column of the current row
    lvCheckRow%,          // Row index used to check for matching keys
    lvProcessedRows$[],   // Array to track which rows have been processed
    lvGroupedData$[][],   // Output array to store grouped rows
    lvFound$;             // Marker string to indicate a row has been processed

copy 0 to lvKeyIndex%;
copy 0 to lvCurrentRow%;
copy 0 to lvNewRowIndex%;
copy "found" to lvFound$;

// Number of rows
copy getSize(pvData$) to lvTotalRows%;
// Depth / number of columns
copy getSize(pvData$[1]) to lvTotalColumns%;

// Outer loop: iterate through the array
for lvCurrentRow% = 0 to lvTotalRows% - 1    
    if (lvProcessedRows$[lvCurrentRow%] &!= lvFound$)
        copy pvData$[lvCurrentRow%][lvKeyIndex%] to lvCurrentKey$;
        
        // Inner loop: check all rows from current to end for matching keys        
        for lvCheckRow% = lvCurrentRow% to lvTotalRows% - 1
		
            if (pvData$[lvCheckRow%][lvKeyIndex%] &= lvCurrentKey$)

				traceln("lvCurrentKey: " & lvCurrentKey$);
			
                for lvColumnIndex% = 0 TO lvTotalColumns% - 1
                    copy pvData$[lvCheckRow%][lvColumnIndex%] to lvGroupedData$[lvNewRowIndex%][lvColumnIndex%];
                next
				
                // Mark the row as processed and increment the index 
                // to examine the next row for grouping
                copy lvFound$ to lvProcessedRows$[lvCheckRow%];
                copy lvNewRowIndex% + 1 to lvNewRowIndex%;
                
            endif
        next
    endif
next

// return array grouped by first given key
exitProc(lvGroupedData$);

Easily converted to NET 9 C# 12 using CoPilot / ChatGPT5, use what data content you'd prefer and run some iterations in a Console App to check program flow