@fileverse-dev/formulajs 4.4.18 → 4.4.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/cjs/index.cjs CHANGED
@@ -1270,75 +1270,79 @@ function ROWS(array) {
1270
1270
  * @param {*} by_col Optional. A logical value indicating the desired sort direction; FALSE to sort by row (default), TRUE to sort by column
1271
1271
  * @returns
1272
1272
  */
1273
- function SORT(array, sort_index = 1, is_ascending, by_col = false) {
1274
- if (!array || !Array.isArray(array)) return na;
1275
- if (array.length === 0) return 0;
1273
+ function SORT(inputArray, sortIndex = 1, isAscending, sortByColumn = false) {
1274
+ if (!inputArray || !Array.isArray(inputArray)) return na;
1275
+ if (inputArray.length === 0) return 0;
1276
1276
 
1277
- let idx = parseNumber(sort_index);
1278
- if (!idx || idx < 1) return value;
1279
- idx = idx - 1;
1277
+ let sortColumnIndex = parseNumber(sortIndex);
1278
+ if (!sortColumnIndex || sortColumnIndex < 1) return value;
1279
+ sortColumnIndex = sortColumnIndex - 1;
1280
1280
 
1281
- const sortOrderNumber = is_ascending === 'FALSE' ? -1 : 1;
1282
- let order = parseNumber(sortOrderNumber);
1283
- if (order !== 1 && order !== -1) return value;
1281
+ const sortDirection = isAscending?.toLowerCase() === 'false' ? -1 : 1;
1282
+ const parsedSortDirection = parseNumber(sortDirection);
1283
+ if (parsedSortDirection !== 1 && parsedSortDirection !== -1) return value;
1284
1284
 
1285
- const byCol = parseBool(by_col);
1286
- if (typeof byCol !== "boolean") return name;
1287
1285
 
1288
- // Rectangularize then orient
1289
- const matrix = fillMatrix(array);
1290
- const working = byCol ? transpose(matrix) : matrix;
1286
+ const isSortByColumn = parseBool(sortByColumn);
1287
+ if (typeof isSortByColumn !== "boolean") return name;
1288
+
1289
+
1290
+ const normalizedMatrix = fillMatrix(inputArray);
1291
+ const orientedMatrix = isSortByColumn
1292
+ ? transpose(normalizedMatrix)
1293
+ : normalizedMatrix;
1291
1294
 
1292
- if (!working.length || !working[0] || idx >= working[0].length) {
1293
- return value; // out of bounds
1295
+ if (!orientedMatrix.length || !orientedMatrix[0] || sortColumnIndex >= orientedMatrix[0].length) {
1296
+ return value;
1294
1297
  }
1295
1298
 
1296
- // Helpers (aiming for spreadsheet-ish behavior)
1297
- const isBlank = (v) => v === "" || v === null || v === undefined;
1299
+ const isBlank = (value) => value === "" || value === null || value === undefined;
1298
1300
 
1299
- const cmp = (a, b) => {
1300
- // Blanks last (ascending); we'll multiply by order later for descending.
1301
+ // Comparator for sorting values
1302
+ const compareValues = (a, b) => {
1301
1303
  const aBlank = isBlank(a);
1302
1304
  const bBlank = isBlank(b);
1303
1305
  if (aBlank && bBlank) return 0;
1304
1306
  if (aBlank) return 1;
1305
1307
  if (bBlank) return -1;
1306
1308
 
1307
- // If both parse as finite numbers, compare numerically
1308
- const na = parseNumber(a);
1309
- const nb = parseNumber(b);
1310
- const aNum = Number.isFinite(na);
1311
- const bNum = Number.isFinite(nb);
1309
+ // Numeric comparison if possible
1310
+ const parsedA = parseNumber(a);
1311
+ const parsedB = parseNumber(b);
1312
+ const isANumber = Number.isFinite(parsedA);
1313
+ const isBNumber = Number.isFinite(parsedB);
1312
1314
 
1313
- if (aNum && bNum) {
1314
- if (na < nb) return -1;
1315
- if (na > nb) return 1;
1315
+ if (isANumber && isBNumber) {
1316
+ if (parsedA < parsedB) return -1;
1317
+ if (parsedA > parsedB) return 1;
1316
1318
  return 0;
1317
1319
  }
1318
1320
 
1319
- // Fallback: case-insensitive string compare
1320
- const sa = (parseString(a) ?? "").toString().toLowerCase();
1321
- const sb = (parseString(b) ?? "").toString().toLowerCase();
1322
- if (sa < sb) return -1;
1323
- if (sa > sb) return 1;
1321
+ // Fallback: case-insensitive string comparison
1322
+ const stringA = (parseString(a) ?? "").toString().toLowerCase();
1323
+ const stringB = (parseString(b) ?? "").toString().toLowerCase();
1324
+ if (stringA < stringB) return -1;
1325
+ if (stringA > stringB) return 1;
1324
1326
  return 0;
1325
1327
  };
1326
1328
 
1327
- // Stable sort: decorate with original index
1328
- const decorated = working.map((row, i) => ({ row, i }));
1329
+ const rowsWithOriginalIndex = orientedMatrix.map((row, rowIndex) => ({ row, rowIndex }));
1329
1330
 
1330
- decorated.sort((A, B) => {
1331
- const base = cmp(A.row[idx], B.row[idx]);
1332
- if (base !== 0) return base * order;
1333
- // stable tiebreaker: original order
1334
- return A.i - B.i;
1331
+ rowsWithOriginalIndex.sort((rowA, rowB) => {
1332
+ const baseComparison = compareValues(rowA.row[sortColumnIndex], rowB.row[sortColumnIndex]);
1333
+ if (baseComparison !== 0) return baseComparison * parsedSortDirection;
1334
+ return rowA.rowIndex - rowB.rowIndex;
1335
1335
  });
1336
1336
 
1337
- const sorted = decorated.map((d) => d.row);
1338
- return byCol ? transpose(sorted) : sorted;
1337
+ // Extract sorted rows
1338
+ const sortedMatrix = rowsWithOriginalIndex.map((item) => item.row);
1339
+
1340
+ // Return rows or columns depending on orientation
1341
+ return isSortByColumn ? transpose(sortedMatrix) : sortedMatrix;
1339
1342
  }
1340
1343
 
1341
1344
 
1345
+
1342
1346
  /**
1343
1347
  * Returns the transpose of an array.
1344
1348
  *
package/lib/esm/index.mjs CHANGED
@@ -1268,75 +1268,79 @@ function ROWS(array) {
1268
1268
  * @param {*} by_col Optional. A logical value indicating the desired sort direction; FALSE to sort by row (default), TRUE to sort by column
1269
1269
  * @returns
1270
1270
  */
1271
- function SORT(array, sort_index = 1, is_ascending, by_col = false) {
1272
- if (!array || !Array.isArray(array)) return na;
1273
- if (array.length === 0) return 0;
1271
+ function SORT(inputArray, sortIndex = 1, isAscending, sortByColumn = false) {
1272
+ if (!inputArray || !Array.isArray(inputArray)) return na;
1273
+ if (inputArray.length === 0) return 0;
1274
1274
 
1275
- let idx = parseNumber(sort_index);
1276
- if (!idx || idx < 1) return value;
1277
- idx = idx - 1;
1275
+ let sortColumnIndex = parseNumber(sortIndex);
1276
+ if (!sortColumnIndex || sortColumnIndex < 1) return value;
1277
+ sortColumnIndex = sortColumnIndex - 1;
1278
1278
 
1279
- const sortOrderNumber = is_ascending === 'FALSE' ? -1 : 1;
1280
- let order = parseNumber(sortOrderNumber);
1281
- if (order !== 1 && order !== -1) return value;
1279
+ const sortDirection = isAscending?.toLowerCase() === 'false' ? -1 : 1;
1280
+ const parsedSortDirection = parseNumber(sortDirection);
1281
+ if (parsedSortDirection !== 1 && parsedSortDirection !== -1) return value;
1282
1282
 
1283
- const byCol = parseBool(by_col);
1284
- if (typeof byCol !== "boolean") return name;
1285
1283
 
1286
- // Rectangularize then orient
1287
- const matrix = fillMatrix(array);
1288
- const working = byCol ? transpose(matrix) : matrix;
1284
+ const isSortByColumn = parseBool(sortByColumn);
1285
+ if (typeof isSortByColumn !== "boolean") return name;
1286
+
1287
+
1288
+ const normalizedMatrix = fillMatrix(inputArray);
1289
+ const orientedMatrix = isSortByColumn
1290
+ ? transpose(normalizedMatrix)
1291
+ : normalizedMatrix;
1289
1292
 
1290
- if (!working.length || !working[0] || idx >= working[0].length) {
1291
- return value; // out of bounds
1293
+ if (!orientedMatrix.length || !orientedMatrix[0] || sortColumnIndex >= orientedMatrix[0].length) {
1294
+ return value;
1292
1295
  }
1293
1296
 
1294
- // Helpers (aiming for spreadsheet-ish behavior)
1295
- const isBlank = (v) => v === "" || v === null || v === undefined;
1297
+ const isBlank = (value) => value === "" || value === null || value === undefined;
1296
1298
 
1297
- const cmp = (a, b) => {
1298
- // Blanks last (ascending); we'll multiply by order later for descending.
1299
+ // Comparator for sorting values
1300
+ const compareValues = (a, b) => {
1299
1301
  const aBlank = isBlank(a);
1300
1302
  const bBlank = isBlank(b);
1301
1303
  if (aBlank && bBlank) return 0;
1302
1304
  if (aBlank) return 1;
1303
1305
  if (bBlank) return -1;
1304
1306
 
1305
- // If both parse as finite numbers, compare numerically
1306
- const na = parseNumber(a);
1307
- const nb = parseNumber(b);
1308
- const aNum = Number.isFinite(na);
1309
- const bNum = Number.isFinite(nb);
1307
+ // Numeric comparison if possible
1308
+ const parsedA = parseNumber(a);
1309
+ const parsedB = parseNumber(b);
1310
+ const isANumber = Number.isFinite(parsedA);
1311
+ const isBNumber = Number.isFinite(parsedB);
1310
1312
 
1311
- if (aNum && bNum) {
1312
- if (na < nb) return -1;
1313
- if (na > nb) return 1;
1313
+ if (isANumber && isBNumber) {
1314
+ if (parsedA < parsedB) return -1;
1315
+ if (parsedA > parsedB) return 1;
1314
1316
  return 0;
1315
1317
  }
1316
1318
 
1317
- // Fallback: case-insensitive string compare
1318
- const sa = (parseString(a) ?? "").toString().toLowerCase();
1319
- const sb = (parseString(b) ?? "").toString().toLowerCase();
1320
- if (sa < sb) return -1;
1321
- if (sa > sb) return 1;
1319
+ // Fallback: case-insensitive string comparison
1320
+ const stringA = (parseString(a) ?? "").toString().toLowerCase();
1321
+ const stringB = (parseString(b) ?? "").toString().toLowerCase();
1322
+ if (stringA < stringB) return -1;
1323
+ if (stringA > stringB) return 1;
1322
1324
  return 0;
1323
1325
  };
1324
1326
 
1325
- // Stable sort: decorate with original index
1326
- const decorated = working.map((row, i) => ({ row, i }));
1327
+ const rowsWithOriginalIndex = orientedMatrix.map((row, rowIndex) => ({ row, rowIndex }));
1327
1328
 
1328
- decorated.sort((A, B) => {
1329
- const base = cmp(A.row[idx], B.row[idx]);
1330
- if (base !== 0) return base * order;
1331
- // stable tiebreaker: original order
1332
- return A.i - B.i;
1329
+ rowsWithOriginalIndex.sort((rowA, rowB) => {
1330
+ const baseComparison = compareValues(rowA.row[sortColumnIndex], rowB.row[sortColumnIndex]);
1331
+ if (baseComparison !== 0) return baseComparison * parsedSortDirection;
1332
+ return rowA.rowIndex - rowB.rowIndex;
1333
1333
  });
1334
1334
 
1335
- const sorted = decorated.map((d) => d.row);
1336
- return byCol ? transpose(sorted) : sorted;
1335
+ // Extract sorted rows
1336
+ const sortedMatrix = rowsWithOriginalIndex.map((item) => item.row);
1337
+
1338
+ // Return rows or columns depending on orientation
1339
+ return isSortByColumn ? transpose(sortedMatrix) : sortedMatrix;
1337
1340
  }
1338
1341
 
1339
1342
 
1343
+
1340
1344
  /**
1341
1345
  * Returns the transpose of an array.
1342
1346
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fileverse-dev/formulajs",
3
- "version": "4.4.18",
3
+ "version": "4.4.20",
4
4
  "description": "JavaScript implementation of most Microsoft Excel formula functions",
5
5
  "author": "Formulajs",
6
6
  "publishConfig": {
@@ -3806,7 +3806,7 @@ export function SMARTCONTRACT(...args: any[]): Promise<any>;
3806
3806
  * @param {*} by_col Optional. A logical value indicating the desired sort direction; FALSE to sort by row (default), TRUE to sort by column
3807
3807
  * @returns
3808
3808
  */
3809
- export function SORT(array: any, sort_index: any, is_ascending: any, by_col?: any): any;
3809
+ export function SORT(inputArray: any, sortIndex: number, isAscending: any, sortByColumn?: boolean): any;
3810
3810
  /**
3811
3811
  * Returns a positive square root.
3812
3812
  *
@@ -3806,7 +3806,7 @@ export function SMARTCONTRACT(...args: any[]): Promise<any>;
3806
3806
  * @param {*} by_col Optional. A logical value indicating the desired sort direction; FALSE to sort by row (default), TRUE to sort by column
3807
3807
  * @returns
3808
3808
  */
3809
- export function SORT(array: any, sort_index: any, is_ascending: any, by_col?: any): any;
3809
+ export function SORT(inputArray: any, sortIndex: number, isAscending: any, sortByColumn?: boolean): any;
3810
3810
  /**
3811
3811
  * Returns a positive square root.
3812
3812
  *