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